It really depends on what's most readable for your clients. I can think of a couple of options:
1) The inherited interface, though I'm not a fan of hiding, and I think it makes it a bit ugly for any VB.NET or explicit clients to implement:
interface IObject {
bool IsSecureConnection { get; }
// ... other interface definitions //
}
interface ISecurableObject : IObject {
new bool IsSecureConnection { get; set; }
}
2) Split the set from the property, with an inherited interface:
interface IObject {
bool IsSecureConnection { get; }
// ... other interface definitions //
}
interface ISecurableObject : IObject {
void SetConnectionSecurity(bool isSecure);
}
3) Changing the semantics to try and acquire a secure connection, which an implementer is free to just return false from:
interface ISecurable {
bool IsSecureConnection { get; }
bool TrySecureConnection();
}
4) Add an additional check property:
interface ISecurable {
bool IsSecureConnection { get; set; }
bool SupportsSecureConnection { get; }
}
All of these are, IMO, valid designs for certain contexts. Since I don't have any info on the use cases, except that almost all of the time a secure connection can be established - I'd probably vote for 3. It's easy to implement, there's only 1 code path for clients, and there's no exception mechanism (which is another form of coupling). You do have the danger of clients not checking the return from TrySecureConnection, but I think it has less issues than the other choices.
If clients prefer a secure connection, but don't require one - then 1 has the disadvantage of either requiring overloads or the client to check if their IObject is really a ISecurableObject. Both of which are kind of ugly. 2 has the same problem, but without the troublesome new/shadows trickery. However, if some clients require a secure connection, then this (or 2) is probably the way to go - otherwise, you can't really use type safety to enforce a securable connection.
4, while a valid design IMO (some would disagree - see reactions to IO.Stream) is easy for clients to get wrong. If 90% of implementers are securable, it's easy to not check the SupportsSecureConnection. There's also an implementer's choice of either throwing an exception or discarding the IsSecureConnection = true call if it's not supported, requiring clients to both catch and check the new value of IsSecureConnection.