Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing methods from being inherited

I have a base class Foo that is concrete and contains 30 methods which are relevant to its subclasses.

Now I've come across a situation that is specific only to the base class,and I want to create a method that cannot be inherited, is this possible?

Class Foo 
{
   /* ... inheritable methods ... */

   /* non-inheritable method */
   public bool FooSpecificMethod()
   { 
      return true;
   } 
}

Class Bar : Foo
{
    /* Bar specific methods */
}

var bar = new Bar();
bar.FooSpecificMethod(); /* is there any way to get this to throw compiler error */

EDIT

I'm not sure if I was clear originally.

I do understand the principles of inheritance, and I understand the Liskov substitution principle. In this case there is a single exception that ONLY deals with the 'un-inherited' case, and so I did not want to create an 'uninheritedFoo' subclass.

I was asking if it is technically possible to create a situation where foo.FooSpecificMethod() is a valid and publicly accessible method, but subclassoffoo.FooSpecificMethod() throws a compiler error.

Essentially I want a sealed method on an unsealed class.

like image 812
DevinB Avatar asked Apr 07 '09 23:04

DevinB


People also ask

How can we avoid a method from being inherited?

You could use other extension methods than subclassing in this case. For example, you might want to consider using events or delegates to extend the behavior instead of allowing the object to be subclasses. Trying to do what you are accomplishing is basically trying to prevent the main goals of inheritance.

Is it possible to restrict inheritance?

You cannot restrict inheritance in javascript. If you have a public constructor function that initializes an object, any other object can use it to make a derived object.

How can we set the class to be inherited but prevent the method from being over ridden?

Can you allow class to be inherited, but prevent the method from being over-ridden? Yes, just leave the class public and make the method sealed.

How can we prevent class from being inherited in C#?

In C# you use the sealed keyword in order to prevent a class from being inherited.


1 Answers

I would rethink the need for this.

If you are using inheritance, you are suggesting that "Bar" IS A "Foo". If "Bar" is always a "Foo", methods that work on "Foo" should also work on "Bar".

If this isn't the case, I would rework this as a private method. Publically, Bar should always be a Foo.


Just to take this one step further -

If you could do this, things would get very complicated. You could have situations where:

Foo myBar = new Bar(); // This is legal
myBar.FooSpecificMethod(); // What should this do?  
                           // It's declared a Foo, but is acutally a Bar

You can actually force this behavior using reflection, though. I think it's a bad idea, but FooSpecificMethod() could check the type of this, and if it isn't typeof(Foo), throw an exception. This would be very confusing, and have a very bad smell.


Edit in response to question's edit:

There is no way for the compiler to enforce what you are asking. If you really want to force the compiler to check this, and prevent this, you really should consider making Foo a sealed class. You could use other extension methods than subclassing in this case.

For example, you might want to consider using events or delegates to extend the behavior instead of allowing the object to be subclasses.

Trying to do what you are accomplishing is basically trying to prevent the main goals of inheritance.

like image 149
Reed Copsey Avatar answered Sep 20 '22 16:09

Reed Copsey