How do you make members inaccessible to sub-derived classes? - c#

Say I have a base class like this:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
//...
}
}
Then I inherit this class in a separate assembly:
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
MyMethod(MyConstantString);
}
}
I now want to make sure that any other class that inherits from MyDerivedClass does not have access to the MyBaseClass.MyMethod() method. (To clarify, I still want to be able to call MyDerivedClass.MyMethod() with no parameters)
I tried using protected internal but that didn't work.
Update: I'm trying to do this because the application I'm working on has a bunch of separate programs that use a base class. There are 5 different "types" of programs, each performs a specific, separate function but they all have some common code that I am trying to abstract into this base class. The common code is 99% the same, differing only slightly depending on what type of program is calling it. This is why I have my base class taking a string parameter in the example which then disappears in the derived base class, as that class knows it performs role x so it tells its base class accordingly.

Then I would instead of inheritance use composition in the MyDerivedClass. So all derived classes from this class does not know the methods from MyBaseClass. The class MyBaseClass would i make package visible so it is not possible to use it.
abstract class MyBaseClass
{
void MyMethod(string myVariable)
{
//...
}
}
abstract class MyDerivedClass
{
static readonly string MyConstantString = "Hello";
private MyBaseClass baseClass;
MyDerivedClass(MyBaseClass baseClass)
{
this.baseClass = baseClass;
}
protected void MyMethod()
{
baseClass.MyMethod(MyConstantString);
}
}
The class names should be changed of course.

This is not quite possible. And it may be a sign that your object design might be in trouble, but that's not a question for SO.
You can try a bit more underhanded approach, though:
public abstract class MyBaseClass
{
protected abstract string MyConstantString { get; }
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected override sealed string MyConstantString => "Hello";
}
Or, more typically, just use the constructor to pass the required argument:
public abstract class MyBaseClass
{
private readonly string myString;
protected MyBaseClass(string myString)
{
this.myString = myString;
}
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected MyBaseClass() : base("Hello") {}
}
Classes derived from MyDerivedClass have no way to change the argument in either case, the second approach is a bit nicer from inheritance perspective (basically, the type is a closure over an argument of its ancestor type).

You cannot stop inheriting classes from calling this method - you have made it protected so your intent is for it to be accessible to classes that inherit from it, whether directly, or via another sub-class.
If you want to keep the inheritance, the best you can do is to throw an error if the sub-class calls it in MyDerivedClass:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
Console.WriteLine(myVariable);
}
}
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
base.MyMethod(MyConstantString);
}
protected new void MyMethod(string myVariable)
{
throw new Exception("Not allowed");
}
}
public class SubDerivedClass : MyDerivedClass
{
static readonly string MyConstantString = "Hello";
public void Foo()
{
MyMethod(MyConstantString);
}
}
When Foo() is called in SubDerivedClass, it will call MyMethod in DerivedClass, which will throw the Exception.

Related

Can a method in a generic abstract base class "know" the most-derived class of its instance?

I'm trying to figure out if this is possible:
public abstract class A<T>
{
public void MyFunc() { ... }
}
public MyClass : A<string>
{
}
Is there a way for MyFunc to know that it has been instanced in a clas of type MyClass ?
I think I need to clarify the question some more:
I have a generic abstract class that contains some core functionality accessed through a singleton.
The user is building a derived class to extend functionalities but the class is not instantiated through a new, but rather by the singleton, contained in the A class once it is accessed.
So, you could see the flow as such:
In the beginning, there is the abstract A<T>
The user creates MyClass : A<string>
The user now accesses: MyClass.MyFunc()
The singleton in MyFunc is then creating the instance
The singleton code is as follows:
public abstract class Singleton<T> where T : class
{
private static readonly Lazy<T> _Instance = new Lazy<T>(CreateInstanceOfT);
protected static T Instance => _Instance.Value;
private static T CreateInstanceOfT()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
}
so:
class A<T>
is really:
class A<T> : Singleton<A>
but what I really need is to, somehow, make it like
Singleton<MyClass>
or whatever class is deriving from
A<T>
I hope this clarifies the question.
Yes, you could do something like:
public abstract class A<T>
{
public void MyFunc()
{
if(this.GetType() == typeof(MyClass))
{
// do your magic
}
}
}
public class MyClass : A<string>
{
}
but why?
Seems to me, if I read your question right, that if the instance of A needs to have MyFunc act differently when it is a MyClass, then MyFunc should be virtual, and overridden in MyClass.
public abstract class A<T>
{
public virtual void MyFunc() { ... }
}
public MyClass : A<string>
{
public override void MyFunc() { ... }
}

Can you override one of the abstract methods in a base class with another base class?

I have a base class that has some abstract methods on it and there are 21 classes that are inheriting from this base class. Now for one of those abstract methods I want to implement it with a common implementation for 6 of the 21 classes so I thought about creating another base class that would do this.
I am open to suggestions but my main purpose of creating another base class between the current base class and the 21 classes is to keep from repeating the same code in 6 of the 21 classes if I didn't have to.
Here is a sample of code to illustrate the situation:
public abstract class FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public virtual string OtherMethod()
{
return this.SomeMethod();
}
}
public abstract class AnotherBase : FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public override OtherMethod()
{
//this is the common method used by 6 of the classes
return "special string for the 6 classes";
}
}
public class Foo1 : FooBase
{
public override string Bar()
{
//do something specific for the Foo1 class here
return "Foo1 special string";
}
public override string SomeMethod()
{
//do something specific for the Foo1 class here
return "Foo1 special string";
}
}
public class Another2 : AnotherBase
{
public override string Bar()
{
//do something specific for the Another2 class here
return "Another special string";
}
public override string SomeMethod()
{
//do something specific for the Another2 class here
return "Another2 special string";
}
}
Yes, you can derive an abstract class from another abstract class
public abstract class FooBase
{
//Base class content
}
public abstract class AnotherBase : FooBase
{
//it is "optional" to make the definition of the abstract methods of the Parent class in here
}
When we say it is optional to define the abstract methods of the parent class inside of the child class, it is mandatory that the child class should be abstract.
public abstract class FooBase
{
public abstract string Bar();
public abstract string SomeMethod();
public abstract string OtherMethod();
}
public abstract class AnotherBase : FooBase
{
public override string OtherMethod()
{
//common method that you wanted to use for 6 of your classes
return "special string for the 6 classes";
}
}
//child class that inherits FooBase where none of the method is defined
public class Foo1 : FooBase
{
public override string Bar()
{
//definition
}
public override string SomeMethod()
{
//definition
}
public override string OtherMethod()
{
//definition
}
}
//child class that inherits AnotheBase that defines OtherMethod
public class Another2 : AnotherBase
{
public override string Bar()
{
//definition
}
public override string SomeMethod()
{
//definition
}
}
So I'm guessing that there will be 5 more classes like Another2 which inherits from AnotherBase that will have a common definition for OtherMethod
Yes, that is entirely possible and frequently done. There is no rule that says that you can have only one base class at the bottommost level of your class hierarchy; subclasses of that class can just as well be abstract and thereby become (somewhat more specialized) base classes for one group of classes indirectly derived from your general base class.
You should specify what exactly those classes do, but.. given the information you provided:
This is the exact problem that the Strategy pattern aims to solve, as shown in the example given in the Head First Design Patterns book.
You have an abstract Duck class, from which other ducks (e.g., RedheadDuck, MallardDuck) derive. The Duck class has a Quack method, that simply displays the string "quack" on the screen.
Now you are told to add a RubberDuck. This guy doesn't quack! So what do you do? Make Quack abstract and let the subclasses decide how to implement this? No, that'll lead to duplicated code.
Instead, you define an IQuackBehaviour interface with a Quack method. From there, you derive two classes, QuackBehaviour and SqueakBehaviour.
public class SqueakBehaviour: IQuackBehaviour
{
public void Quack(){
Console.WriteLine("squeak");
}
}
public class QuackBehaviour: IQuackBehaviour
{
public void Quack(){
Console.WriteLine("quack");
}
}
Now, you compose your ducks with this behaviour as appropriate:
public class MallardDuck : Duck
{
private IQuackBehaviour quackBehaviour = new QuackBehaviour();
public override void Quack()
{
quackBehaviour.Quack();
}
}
public class RubberDuck : Duck
{
private IQuackBehaviour quackBehaviour = new SqueakBehaviour();
public override void Quack()
{
quackBehaviour.Quack();
}
}
You can even inject an instance of IQuackBehaviour through a property if you want the ducks to change their behaviour at runtime.

C# Make a List to hold any derived children of a base class

So I wish to setup an abstract base class to derive children classes from. All the work will take place on the children, but I wanted the children to be able to reference each other.
Here is some pseudo-code:
public abstract class BaseClass<T> : SomeOtherClass {
public List<BaseClass> listOfChildren;
protected T thisChild;
public void DoMoreStuff(){
Debug.Log("Doing more stuff");
}
protected virtual void DoSomething(int i){
listOfChildren[i].DoMoreStuff();
}
}
public class FirstChildClass : BaseClass<FirstChildClass> {
FirstChildClass<T>(){
thisChild = this;
}
public void FirstClassStuff(){
Debug.Log("first class stuff");
}
}
public class SecondChildClass : BaseClass<SecondChildClass> {
public void SecondClassStuff(){
Debug.Log("second class stuff");
}
}
How would I make a generic List to accept any child class?
Will I need to typecast listOfChildren with T to use DoMoreStuff()?
On its own, is there anything else inherently wrong with this setup?
I think you overcompicate the solution. If you don't want to store any data in each node - try to solve this problem then without the generics. I will give you a naive straight-forward implementation of desired behavior as a starting point.
public abstract class BaseClass {
private IList<BaseClass> children = new List<BaseClass>();
public void AddChild(BaseClass child)
{
this.children.Add(child);
}
protected virtual void DoMoreStuff(){
Debug.Write("Doing more stuff");
}
public void DoSomething(int i){
children[i].DoMoreStuff();
}
}
public class FirstChildClass : BaseClass {
protected override void DoMoreStuff(){
Debug.Write("first class more stuff");
}
}
public class SecondChildClass : BaseClass {
protected override void DoMoreStuff(){
Debug.Write("second class more stuff");
}
}
now you can
var root = new FirstChildClass();
root.AddChild(new FirstChildClass());
root.AddChild(new SecondChildClass());
root.AddChild(new FirstChildClass());
root.DoSomething(1); //will print second class more stuff
root.DoSomething(0); //will print first class more stuff
You need to separate between child classes and child data. A child class simply inherits from its parent, to provide a more detailed structure to the data (such as Animal and Dog). A child data, on the other hand, means that whatever the data represents is related to each other (such as Receipt and ReceiptLineItem).
Normally, the two don't overlap. The Receipt class looks nothing like the ReceiptLineItem class, and the Receipt and a ExternalPurchaseOrder have nothing to do with each other, even though they both inherit their structure from Purchase. When they do overlap, you have a tree structure. A Product may be composed of more Products, which each may be composed of yet more Products.
Here's how I'd rewrite your code, assuming you're looking for the first type of inheritance (class structure):
public abstract class BaseClass : SomeOtherClass {
public static List<BaseClass> listOfChildren = new List<BaseClass>();
public void DoMoreStuff(){
Debug.Log("Doing more stuff");
}
protected virtual void DoSomething(int i){
listOfChildren[i].DoMoreStuff();
}
}
public class FirstChildClass : BaseClass {
FirstChildClass(){
// Set some things unique to this class
}
public void FirstClassStuff(){
Debug.Log("first class stuff");
}
}
public class SecondChildClass : BaseClass<SecondChildClass> {
public void SecondClassStuff(){
Debug.Log("second class stuff");
}
}
You could then access the master list as BaseClass.listOfChildren. If you want all children to automatically register themselves, you can add that to the BaseClass constructor:
protected BaseClass()
{
listOfChildren.Add(this);
}

Problem with Abstract class, Interface, Container and methods

I've the following scenario
I've an Interface
public interface ImyInterface
{
void myInterfaceMethod(string param);
}
I've an Abstract Class
public abstract class myAbstractClass
{
public myAbstractClass()
{
//something valid for each inherited class
}
public void myAbstractMethod<T>(T param)
{
//something with T param
}
}
I've a class that inherits from myAbstractClass and implements ImyInterface
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
}
And, finally, I've a class where I'll create a ImyInterface object. At this point I would call myAbstractMethod, but...
public class myFinalClass
{
public void myFinalMethod()
{
ImyInterface myObj = _myContainer<ImyInterface>();
myObj.???
}
}
Obviously there isn't this method because it isn't declared into the interface.
My solution is the following
public interface ImyInterface
{
void myInterfaceMethod(string param);
void myFakeMethod<T>(T param);
}
public class myClass : myAbstractClass, ImyInterface
{
public myClass():base()
{}
public void ThisMethodWillNeverCall()
{
// nothing to do
}
//--- a fake method
public void myFakeMethod<T>(T param)
{
base.myAbstractMethod<T>(param);
}
}
Is there any other solution better than mine?
Thank you!
First of all, your naming convention is a mess. Read up on the guidelines that Microsoft have made.
It's also hard to tell what you are trying to achieve based on your example.
Back to your question:
You should only access an interface to work with that interface. Don't try to make any magic stuff with classes/interfaces to get them working together. That usually means that the class shouldn't try to implement the interface.
It's better that you create a new interface which have the features that you want and let your class implement both.

Is there a way to hide the methods partially in child classes?

This question seems weird, but i came across this question in one of the interviews recently.
I ve been asked, is there a way in c# to hide the methods partially in a inherited child classes?. Assume the base class A, exposed 4 methods. Class B implements A and it will only have the access to first 2 methods and Class C implements A will only have the access to last 2 methods.
I know we can do this way
public interface IFirstOne
{
void method1();
void method2();
}
public interface ISecondOne
{
void method3();
void method4();
}
class baseClass : IFirstOne, ISecondOne
{
#region IFirstOne Members
public void method1()
{
throw new NotImplementedException();
}
public void method2()
{
throw new NotImplementedException();
}
#endregion
#region ISecondOne Members
public void method3()
{
throw new NotImplementedException();
}
public void method4()
{
throw new NotImplementedException();
}
#endregion
}
class firstChild<T> where T : IFirstOne, new()
{
public void DoTest()
{
T objt = new T();
objt.method1();
objt.method2();
}
}
class secondChild<T> where T : ISecondOne, new()
{
public void DoTest()
{
T objt = new T();
objt.method3();
objt.method4();
}
}
But what they wanted is different. They wanted to hide these classes on inheriting from baseclasses. something like this
class baseClass : IFirstOne, ISecondOne
{
#region IFirstOne Members
baseClass()
{
}
public void method1()
{
throw new NotImplementedException();
}
public void method2()
{
throw new NotImplementedException();
}
#endregion
#region ISecondOne Members
public void method3()
{
throw new NotImplementedException();
}
public void method4()
{
throw new NotImplementedException();
}
#endregion
}
class firstChild : baseClass.IFirstOne //I know this syntax is weird, but something similar in the functionality
{
public void DoTest()
{
method1();
method2();
}
}
class secondChild : baseClass.ISecondOne
{
public void DoTest()
{
method3();
method4();
}
}
is there a way in c# we can achieve something like this...
I did it by having 1 main base class and 2 sub bases.
// Start with Base class of all methods
public class MyBase
{
protected void Method1()
{
}
protected void Method2()
{
}
protected void Method3()
{
}
protected void Method4()
{
}
}
// Create a A base class only exposing the methods that are allowed to the A class
public class MyBaseA : MyBase
{
public new void Method1()
{
base.Method1();
}
public new void Method2()
{
base.Method2();
}
}
// Create a A base class only exposing the methods that are allowed to the B class
public class MyBaseB : MyBase
{
public new void Method3()
{
base.Method3();
}
public new void Method4()
{
base.Method4();
}
}
// Create classes A and B
public class A : MyBaseA {}
public class B : MyBaseB {}
public class MyClass
{
void Test()
{
A a = new A();
// No access to Method 3 or 4
a.Method1();
a.Method2();
B b = new B();
// No Access to 1 or 2
b.Method3();
b.Method4();
}
}
Although you can't do exactly what you want, you could use explicit interface implementation to help, in which the interface members are only exposed if it is explicitly cast to that interface...
Perhaps the interviewer may have been referring to method hiding?
This is where you declare a method with the same signature as on in your base class - but you do not use the override keyword (either because you don't or you can't - as when the method in the base class is non-virtual).
Method hiding, as opposed to overriding, allows you to define a completely different method - one that is only callable through a reference to the derived class. If called through a reference to the base class you will call the original method on the base class.
Don't use inheritance. It makes the public or protected facilities of the base class available directly in the derived class, so it simply isn't want you want.
Instead, make the derived class implement the relevant interface, and (if necessary) forward the methods on to a private instance of the underlying class. That is, use composition (or "aggregation") instead of inheritance to extend the original class.
class firstChild : IFirstOne
{
private baseClass _owned = new baseClass();
public void method1() { _owned.method1(); }
// etc.
}
By the way, class names should start with an upper case letter.
There is 2 solutions to hide methods inherited from a base class:
As mentioned by thecoop, you can explicitely implement the interface declaring the methods you want to hide.
Or you can simply create these methods in the base class (not inherited from any interface) and mark them as private.
Regards.
What about injecting base class as an IFirst?
interface IFirst {
void method1();
void method2();
}
interface ISecond {
void method3();
void method4();
}
abstract class Base : IFirst, ISecond {
public abstract void method1();
public abstract void method2();
public abstract void method3();
public abstract void method4();
}
class FirstChild : IFirst {
private readonly IFirst _first;
public FirstChild(IFirst first) {
_first = first;
}
public void method1() { _first.method1(); }
public void method2() { _first.method2(); }
}
Injection keeps you from violating the Interface Segregation Principle. Pure inheritance means that your FirstChild is depending on an interface that it doesn't use. If you want to retain only the IFirst functionality in Base, but ignore the rest of it, then you cannot purely inherit from Base.

Categories