How to change property access level in an inheritance?

Asked

Viewed 170 times

9

I have a class that when inherited I want one of its public attributes to become private, so that the user does not have access to the use of this variable in this class, but I do not know how to do this.

public class Pai {
   public string Exemplo {get; set;}
}

public class Filho : Pai {
   private string Exemplo {get; set;}
}

var pai = new Pai() {
   Exemplo = "OK" // funciona
}

var pai = new Filho() {
   Exemplo = "OK" // não funciona
}

Is there any way to do that? I was watching keyword internal, which could be used in this case, because I’m doing an SDK, but if I use it in Pai, the user also could not access this property on Pai and wanted it to be possible.

3 answers

6

You can’t do this.

In C#, when a method has a public signature, public use of it is required, regardless of its redeclaration.

You can redeclare a method with the same name in the child class using the instruction new. Thus, the redeclaration of the method will overshadow what is being inherited from the parent class if the redeclaration is public.

Redeclaration will create a method Filho.Exemplo and Pai.Exemplo in the same instance. You can use the base to call what comes from the heir.

public class Pai {
    public string Exemplo {get; set;}
}

public class Filho : Pai {
    private new string Exemplo {get => "Teste";}

    public string ExemploHerdado { get {
            return this.Exemplo;
        }
    }
}

public static void Main()
{
    Pai x = new Pai();
    x.Exemplo = "Olá, mundo";

    Filho y = new Filho();
    y.Exemplo = "Foo, bar";

    Console.WriteLine(x.Exemplo);
    Console.WriteLine(y.Exemplo);
    Console.WriteLine(y.ExemploHerdado);
}

See working on .NET Fiddle.

In the above example, y.Exemplo calls the method Pai.Exemplo because what was redeclared in Filho is private. You cannot access a private method from a class, so you call what is public.

When I call Filho.ExemploHerdado, i return the property redeclared and private Exemplo, with the value I defined.

It would cause confusion and violate class security semantics if that were possible. You would not like to declare a private method and that it be used as a public in an heiress class. The same is true in reverse.

It is good that this obligation exists because it is a contract indicating that you should use the method in the way it was originally declared, and not in any other form of implementation in which it is used.

6


It is not possible, period. They tried to give a solution, but it does not exist. Once the field (and not attribute, this term is wrong, but it is worse because this is not even a field is a property) declared as public it is impossible to decrease its visibility in the inherited classes. Classes that inherit must have all the public API of the inherited class, nothing less, what you’re trying to do is eliminate what already existed in the class, so break the inheritance, so if you want to do this it’s because should not use inheritance there, plain as that.

The question does not help much because it has an abstract example and model correctly in abstract example never works, in a real case we could see some other solution or identify what is the real problem.

But what is clear is that if a field should be public in the more general class and have a more restricted access in the more specific inheritance class is the wrong mechanism. Can’t put protected because besides changing the desired original visibility still doesn’t make it private afterwards. And you can’t replace the property with a new one because it’s not respecting polymorphism, although this could be a solution in some specific case where you don’t want the same inheritance, probably you don’t want that (almost all use of the modifier new in a method is wrong, it was created for quite extraordinary situations), only with the concrete case we could state whether the new serves, but reinforcement that almost never serves.

In some scenario perhaps it would be the case to create another field or property that is private leaving the one that is already public aside, but also think that in this case is using inheritance mistakenly.

A possible coarse gambit is to make the method in the daughter class throw a NotSupportedException and force it to do otherwise, but it’s obviously wrong. I’m not saying you should never do something wrong, but you need to justify it well, you can’t do it because it’s easier or because you can’t do it any other way. Today’s easy is tomorrow’s hard.

Object-oriented programming is about modeling correctly, it only has advantage if it respects how the actual model is, if inventing crazy things to type less code and associate things that should not be associated is bringing more problem to your code not improving.

2

In the Parent class, Attribute in this case must be Protected (Protected). This causes the Son to access, but from outside the class this is not possible, only for internal use.

public class Pai {
   protected string Exemplo {get; set;}
}

In the Son class, there is no need for repetition of the attribute, for this is exactly what inheritance is for.

public class Filho : Pai {

}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.