2

I'm trying to prevent my Base Class to derived one of its method, but it seems impossible to do it in the way I like, I assume I'm doing it wrong.

Could you help please ? :) I really want to use successfully the sealed keyword !

Here is a bit of code :

public class BaseClass
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public sealed void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

What happened is problematic, the keyword sealed isn't allow on a method which is in a first level of derivation. I only have one single derivation level, and what I'm looking for is avoiding MyMethod2 to be derived in the DerivedClass.

But it doesn't seem to be ok :/ Any advice or correction ?

Thanks in advance :)

EDIT : After many comments and lunch pause I'll try to explicit my question !

What I'm try to really do is to prevent my class to use one of the method "she" inherits. Some of you mentioned to use composition instead of inheritance, because it appeared I misunderstood its meaning.

I thought composition was only present in UML not in code. What a composition sounds like in C# code ?

Fikkwix
  • 167
  • 3
  • 10
  • 2
    I just don't understand why you need that method to be sealed. If you are just making it for the purpose of not to be overridden then leave it normal it can not be overridden until marked as virtual or abstract. – Jenish Rabadiya Mar 23 '15 at 11:04
  • 1
    This is also a bit of a warning sign that the way classes have been designed is probably wrong. – Robinson Mar 23 '15 at 11:07
  • 1
    whats wrong in making the method "private' ?? – Newton Sheikh Mar 23 '15 at 11:08
  • @JenishRabadiya it can't be overridden yes, but the derived class can still access to that method, which I don't want, this is why I'm trying to seled it :/ – Fikkwix Mar 23 '15 at 11:26
  • @Fikkwix Can't you make it just private to prevent it accessible in derived class? – Jenish Rabadiya Mar 23 '15 at 11:29
  • @JenishRabadiya If I make it private, I'll not be able to access it from exterior, same as protected, or I need to access it from another program which use this class as a compiled DLL. But I don't want the derived class to be able to access it ! I should had precise it :/ – Fikkwix Mar 23 '15 at 11:36
  • 1
    @Fikkwix If it's accessible to the outside then it is accessible to derived classes as well. Overriding and sealing are different than accessibility of a method. – juharr Mar 23 '15 at 11:45
  • @Fikkwix also note injecting such a behavior defeats the use of inheritance. – Jenish Rabadiya Mar 23 '15 at 11:52
  • This seems like a [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). You might need composition instead of inheritance, but we can not tell from the general example given. – juharr Mar 23 '15 at 11:54
  • unlike java, in c# methods are sealed by default. you add the "virtual" keyword before a method to make it overridable in the subclass. You may want to look into a similar question I asked long ago. http://stackoverflow.com/questions/13858384/sealed-keyword-in-association-with-override – Victor Mukherjee Mar 23 '15 at 12:00
  • @juharr what advice could you give me ? – Fikkwix Mar 23 '15 at 12:03
  • @Fikkwix When posting a question it is good to give a general example of the problem, but it is also good to give a broader explanation of what you are trying to accomplish. – juharr Mar 23 '15 at 12:12

6 Answers6

5

If this is the first level, it is not overridable by derived class unless marked virtual or abstract.

public class BaseClass
{
    public virtual void MyMethod1(string input)
    {
        // Doing stuff here
    }
    public void MyMethod2(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    public override void MyMethod1(string input){..}

    /// MyMethod2 is not overridable
}

Based on your comments below, it seems like what you really want is composition, not inheritance; that is to say that DerivedClass should be able to access some functionality on the BaseClass but should not be able to change it in any way. This may look like the below for your class example.

public class CompositeFunctionality
{
    public void MyMethod1(string input)
    {
        // Doing stuff here
    }
}
public class BaseClass
{
    private CompositeFunctionality composite = new CompositeFunctionality();
    public void MyMethod2(string input)
    {
        // this is accessible in the base class
        composite.MyMethod1();
    }
}

public class DerivedClass : BaseClass
{
    public void MyMethod3(string input)
    {
         // do whatever you want
         // but composite is not accessible here
    }
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • I don't want the method to be override at all, I just want to be not accessible from the derived class. – Fikkwix Mar 23 '15 at 11:20
  • 1
    @Fikkwix then you're funamentally misunderstanding inheritance. It sounds more like you want composition than inheritance. – Jamiec Mar 23 '15 at 12:10
  • @Fikkwix see update - its a bit of a contrived example, but hopefully you get the gist – Jamiec Mar 23 '15 at 13:57
  • I use your method it works, but not in the way I'd like to... In fact with your method, in the DerivedClass MyMethod2 will be still accessible... I should change the way I think I guess >_<' – Fikkwix Mar 23 '15 at 15:16
  • I was already using a composition inside my code. But not in a correct way, that's explain everything which was going wrong ^^ Thanks a lot for your help ! – Fikkwix Mar 24 '15 at 07:48
4

You can only seal a method/property that overrides a virtual method in a base class. Your MyMethod2 isn't virtual, so can't be sealed. In fact it's implicitly sealed by the fact it isn't virtual!

Sean
  • 60,939
  • 11
  • 97
  • 136
1

You need another level of inheritance to be able to use sealed. You can mark the method virtual in the base class, and override sealed it in the second class.

You could make the "absolute base" abstract, so it's not possible to instantiate it, then inherit from it to implement and seal it:

public abstract class VeryBaseClass
{
    public abstract void MyMethod2(string input);
}

public class BaseClass : VeryBaseClass
{
    public override sealed void MyMethod2(string input)
    {

    }
}

public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
}

But like @Jenish says, methods are sealed by default in C#.

On the contrary, to be able to override a method it must be marked virtual anyway, so your problem doesn't seem to be a problem at all. Just mark MyMethod1 as virtual so you can override it, and MyMethod2 will remain non-virtual so non-overridable at all.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Does your solution act like a composition link to a inheritance ? Plus it will work, just I'd like to avoid to add another class to my project if it's not absolutely necessary. – Fikkwix Mar 23 '15 at 13:33
  • I tried it like you wrote it, but still my method MyMethod2 is available from my DerivedClass, I don't understand why... – Fikkwix Mar 23 '15 at 13:54
  • @Fikkwix that means you don't know what `sealed` means. If you want to hide a method from outside that class, mark it `private` or `protected`. – CodeCaster Mar 23 '15 at 13:54
  • Maybe, could you explain ? To me sealed means the method will not be present in the derived class, however it seems I misunderstood... – Fikkwix Mar 23 '15 at 14:14
0

The sealed keyword is implied to any method in a base class that isn't already virtual or abstract (and therefore overridable).

See this link on MSDN for more information

Daniel Casserly
  • 3,552
  • 2
  • 29
  • 60
0

try like this..

class Base 
{
 public virtual void Test() { ... }
}

class Subclass1 : Base 
{
 public sealed override void Test() { ... }
}

class Subclass2 : Subclass1 
{
 public override void Test() { ... } // FAILS!
// If `Subclass1.Test` was not sealed, it would've compiled correctly.
}
Nalaka
  • 1,165
  • 7
  • 12
  • I've seen that example out there, but it's not what I'm trying to do. I don't want the method to be accessible at all in the derived class. – Fikkwix Mar 23 '15 at 11:23
0

I am renaming methods for a better understanding.

public class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}
public class DerivedClass : BaseClass
{
    // Other fields and stuff over there
    //MethodoBeInherited should be available
    //MethodNotToBeInherited should not be available
}

The condition you want is not possible using this kind of hierarchy(Is a relationship), because DervicedClass is a BaseClass. So on the rules of inheritance you are bound to have access to all BaseClass public methods.

But there is an alternative to solve this using - Has a relationship. Its not possible to inherit and achieve what you wanted as you will break the inheritance rule. So making the derived class composed of a base class you would be able to achieve it.

interface I
{
    void MethodToBeInherited(string input)
}

class BaseClass
{
    public void MethodToBeInherited(string input)
    {
        // Doing stuff here
    }
    public void MethodNotToBeInherited(string input)
    {
        // Doing stuff here
    }
}

class DerivedClass : I
{
    public void MethodToBeInherited(string input)
    {
        b.MethodToBeInherited(input);
    }

    private BaseClass b;
}
Carbine
  • 7,849
  • 4
  • 30
  • 54
  • An interface isn't what I expected but why not ! I'll try this if there are no other solutions working. Thanks for your answer :) – Fikkwix Mar 23 '15 at 11:38
  • This doesn't seem right. The interface has a method called `MethodToBeInherited` but the `DrivedClass` that implements that interface has a method called `MethodNotToBeInherited`? Did you mean to apply the interface to the `BaseClass` so that the `MethodNotToBeInherited` is not visible to the `DerivedClass` and then refer to the interface in the `DerivedClass`? – juharr Mar 23 '15 at 11:51
  • Thanks for pointing it, it was a typo. I wanted to expose `MethodToBeInherited` and hide the other one. Corrected the post. – Carbine Mar 23 '15 at 12:01
  • @CarbineCoder I guess that's one interruptation. I thought the OP didn't want the method visible from within the `Derived` class, which it is in your answer. But, maybe they didn't want it visible from outside the `Derived` class. But then the interface should probably be implemented by both classes in that case. – juharr Mar 23 '15 at 12:06
  • True thats another way, its just upto the OP to decide. But if Interface is implemented by both Base and derived, they are no longer base and derived and they will lie on the same level of hierarchy. And if it goes like `Derived:Base,I` then the method will end up being visible. Then again its up to the OP to choose the approach based on the context of his problem. – Carbine Mar 23 '15 at 12:10