C # - Is it possible to hide hidden methods (e.g. private ones for a derived class)

Suppose I have a BaseClass with the public methods A and B, and I create a DerivedClass through inheritance.

eg.

public DerivedClass : BaseClass {} 

Now I want to develop a C method in DerivedClass that uses A and B. Is there a way to override A and B methods to be private in DerivedClass, so that only C method is exposed to those who want to use my DerivedClass

+47
c # class
Sep 19 '08 at 23:29
source share
9 answers

It is impossible, why?

In C #, it is imposed on you that if you inherit publicly available methods, you must make them publicly available. Otherwise, they expect that you will not extract from the class in the first place.

Instead of using is-a relationships, you will need to use has-a relationships.

Language developers do not allow this specifically so that you use inheritance more correctly.

For example, you might accidentally confuse the Car class to get from the Engine class to get its functionality. But Engine is the functionality that the car uses. So you would like to use a has-a relationship. The Car user does not want access to the Engine interface. And the car itself should not confuse the methods of the Engine with its own. Nor Car of future derivations.

Therefore, they do not protect you from incorrect inheritance hierarchies.

What should you do instead?

Instead, you should implement interfaces. This gives you the opportunity to have functionality using has-a relationships.

Other languages:

In C ++, you simply specify the modifier in front of the base class private, public or protected. This makes all members of the database available for this access level. It seems silly to me that you cannot do the same in C #.

Modified Code:

 interface I { void C(); } class BaseClass { public void A() { MessageBox.Show("A"); } public void B() { MessageBox.Show("B"); } } class Derived : I { public void C() { bA(); bB(); } private BaseClass b; } 

I understand that the names of the above classes are a bit controversial :)

Other offers:

Others suggested making A () and B () public and throwing exceptions. But this does not make a friendly class for people, and it does not make sense.

+63
Sep 19 '08 at 23:56
source share

If, for example, you try to inherit from List<object> , and you want to hide the direct member Add(object _ob) :

 // the only way to hide [Obsolete("This is not supported in this class.", true)] public new void Add(object _ob) { throw NotImplementedException("Don't use!!"); } 

This is not the preferred solution, but it does the job. Intellisense still accepts, but at compile time you get an error message:

error CS0619: "TestConsole.TestClass.Add (TestConsole.TestObject)" deprecated: "This is not supported in this class."

+15
Jul 01 2018-10-10T00:
source share

That sounds good. Liskov will not be impressed.

If you don't want DerivedClass users to be able to access the DeriveClass.A () and DerivedClass.B () methods, I would suggest that DerivedClass should implement some open IWhateverMethodCIsAbout interface, and DerivedClass consumers should actually talk to IWhateverMethodCIsAbout and don't know anything about implementations of BaseClass or DerivedClass in general.

+6
Sep 19 '08 at 23:35
source share

You need composition, not inheritance.

 class Plane { public Fly() { .. } public string GetPilot() {...} } 

Now, if you need a special type of aircraft, such as one that has PairOfWings = 2, but otherwise everything that the aircraft can do. You inherit the plane. By this, you declare that your conclusion corresponds to the base class contract and can be replaced without blinking wherever the base class is expected. for example, LogFlight (Plane) will continue to work with the BiPlane instance.

However, if you just need Fly behavior for the new bird that you want to create, and you don't want to support the full base class contract, you compose instead. In this case, reorganize the behavior of the methods for reuse in a new type of flight. Now create and hold links to this class on both Plane and Bird. You do not inherit because Bird does not support the full base class contract ... (for example, it cannot provide GetPilot ()).

For the same reason, you cannot reduce the visibility of base class methods when overriding. you can override and make the base private method publicly available in derivation, but not vice versa. For example, In this example, if I get the Plane type "BadPlane" and then overrides and "hides" GetPilot () - makes it private; the LogFlight client method (Plane p) will work for most Planes, but will explode for "BadPlane" if you need / call GetPilot () to execute LogFlight. Since it is expected that all derivatives of the base class will be "replaceable" wherever the param base class is expected, this should be prohibited.

+5
Sep 20 '08 at 5:18
source share

The only way I can do this that I know of is to use the Has-A relationship and implement only the features you want to open.

+3
Sep 19 '08 at 23:31
source share

@Brian R. Bondy pointed me to an interesting article on hiding through inheritance and the new keyword.

http://msdn.microsoft.com/en-us/library/aa691135(VS.71).aspx

So, in a workaround, I would suggest:

 class BaseClass { public void A() { Console.WriteLine("BaseClass.A"); } public void B() { Console.WriteLine("BaseClass.B"); } } class DerivedClass : BaseClass { new public void A() { throw new NotSupportedException(); } new public void B() { throw new NotSupportedException(); } public void C() { base.A(); base.B(); } } 

Thus, code like this throws a NotSupportedException :

  DerivedClass d = new DerivedClass(); dA(); 
+1
Sep 19 '08 at 23:34
source share

Hiding is a rather slippery slope. The main problems IMO:

  • It depends on the development time the type of instance declaration, this means that if you do something like BaseClass obj = new SubClass (), then calling obj.A (), hiding is defeated. BaseClass.A () is launched.

  • Hiding can very easily hide behavior (or behavior changes) in the base type. This is obviously less of a concern when you own both sides of the equation, or if calling base.xxx is part of your subparticle.

  • If you really own both sides of the base / subclass, then you should be able to develop a more manageable solution than legalized hiding / shadowing.
+1
Sep 20 '08 at 3:13
source share

I would say that if you have a code base with which you want to do this, this is not the best developed code base. This is usually a feature of a class at one level of the hierarchy that requires a specific public signature, while another class derived from this class does not need it.

The upcoming coding paradigm is called Composition over Inheritance. This is directly related to the principles of object-oriented development (especially the principle of shared responsibility and open / closed principle).

Unfortunately, since many of us developers were trained in object orientation, we developed the habit of immediately thinking about inheritance, and not about composition. We tend to have larger classes that have many different responsibilities, simply because they can be contained with the same Real World object. This can lead to class hierarchies that are deeper than 5+.

The unfortunate side effect that developers usually don’t think about when working with inheritance is that inheritance forms one of the most powerful forms of dependency that you can ever inject into your code. Your derived class now depends heavily on the class it was inherited from. This can make your code more fragile in the long run and lead to confusing issues where changing a specific behavior in a base class violates derived classes in obscure ways.

One way to break the code is through interfaces, as indicated in another answer. This is a reasonable thing anyway, since you want the external dependencies of the class to be associated with abstractions, and not with concrete / derived types. This allows you to change the implementation without changing the interface, without changing the line of code in the dependent class.

I would rather not support a system with hundreds / thousands / even more classes that are all small and loosely coupled than with a system that heavily uses polymorphism / inheritance and has fewer classes that are more closely related,

Perhaps the best resource for object-oriented development is a book by Robert C. Martin, Agile Software Development, Principles, Patterns and Practices .

+1
Sep 20 '08 at 4:54
source share

If they are defined publicly in the source class, you cannot redefine them as private in the derived class. However, you can force the public method to throw an exception and implement its own private function.

Edit: Jorge Ferreira is right.

0
Sep 19 '08 at 23:31
source share



All Articles