I want to be able to restrict which classes have access to call a method of another class. I have a the following:
public class A: B
{
private void DoSomething()
{
C.Method1(); // should compile
}
}
public abstract class B
{
}
public class D
{
private void DoSomething()
{
C.Method1(); // shouldn't compile
}
}
public static class C
{
public static void Method1()
{
}
public static void Method2()
{
...
Method1();
...
}
}
All of these classes are in the same assembly, but class B is in a different assembly.
My goal is for class A to be able to call C.Method1, but have class D not able to call C.Method1
I was thinking of making class C a parent class, and have class A inherit class B, but class A already inherits from class B.
Method1 doesn't belong in class A or B.
A practical use for this is when Method1 is a utility method, and should only be called by class A and class C
Without moving methods around, you'd have to make C non-static, make Method1 protected, then have B inherit from C, which would look like:
public class A : B
{
private void DoSomething()
{
C.Method1(); // should compile
}
}
public abstract class B : C
{
}
public class D
{
private void DoSomething()
{
C.Method1(); // shouldn't compile
}
}
public class C
{
protected static void Method1()
{
}
}
Related
I stumbled across an interview question related to OOPS. Here is the question:
There is a base class A with 5 methods. Now how should I design the class such that if a class B inherits class A, only 3 methods are exposed. And if a class C inherits class A, the rest of the 2 methods are exposed.
Any thoughts ??
if A is partial and you have 2 namespaces then:
namespace the_impossible
{
class Program
{
static void Main(string[] args)
{
B b = new B();
C c = new C();
b.m1();
b.m2();
b.m3();
c.m4();
c.m5();
}
}
namespace A_1
{
public partial class A
{
public void m1() { }
public void m2() { }
public void m3() { }
}
}
namespace A_2
{
public partial class A
{
public void m4() { }
public void m5() { }
}
}
class B : A_1.A
{
}
class C : A_2.A
{
}
}
It should not be possible in any object-oriented language, otherwise it would break the Liskov substitution principle. Substituting a B for an A should not reduce its correctness (meaning methods should not suddenly be unavailable)
However, there is still some ambiguity in the question that allows for some "out-of-the-box" thinking. Here are questions I would pose back to the interviewer:
What do you mean by "exposed"?
Do the 5 methods in A have to be public?
Does the "exposition" by C need to be implicit or can the be explicitly exposed (e.g. pass-through)
Based on those answers you could either come up with possible options using internal, explicit interface implementations, etc.
I think it was a trick or even dumb question. To achieve this, we must break the Liskov substitution principle. You shouldn't preseve the hierarchy of the classes.
Maybe you just should use interfaces instead:
public class A {} //why we even need this class?
public class B : A, I3Methods
{
public void Method1() { }
public void Method2() { }
public void Method3() { }
}
public class C : A, I2Methods
{
public void Method4() { }
public void Method5() { }
}
public interface I3Methods
{
void Method1();
void Method2();
void Method3();
}
public interface I2Methods
{
void Method4();
void Method5();
}
The only way I can think of is to have them all private in A and then expose them through encapsulation in B and C... But they are not exposed, only executed... So it is half right.
I also think that's impossible.
But to give an approximate answer:
Make 3 methods in A virtual, then implement them in B. Then override those 2 methods in C.
Nobody says that the 5 methods of class A should be exposed when writing them. In C# you could simply write 5 protected methods in class A and expose those you wish to be accessible by writing some hiding methods with the new modifier like this - although this wouldn't actually expose the methods directly they are merely wrapped.
class A
{
protected void M1() { }
protected void M2() { }
protected void M3() { }
protected void M4() { }
protected void M5() { }
}
class B : A
{
public new void M1()
{
base.M1();
}
public new void M2()
{
base.M2();
}
public new void M3()
{
base.M3();
}
}
class C : A
{
public new void M4()
{
base.M4();
}
public new void M5()
{
base.M5();
}
}
In your comments, you mentioned that you were interested if this could be done in any other language. You can kind of do it in C++ through the use of the using keyword. So, starting with class A:
class A {
public:
int Method1() { return 1; }
int Method2() { return 2; }
int Method3() { return 3; }
int Method4() { return 4; }
int Method5() { return 5; }
};
Then you define class B, using private inheritance (essentially you can't auto cast from B to A and all public methods in A become private methods in B).
class B: private A {
public:
// We want to expose methods 1,2,3 as public so change their accessibility
// with the using keyword
using A::Method1;
using A::Method2;
using A::Method3;
};
Do the same for class C, exposing the other two methods instead:
class C: private A {
public:
using A::Method4;
using A::Method5;
};
Or if you're supposed to expose all the methods through C, simply use public inheritance and everything exists:
class C: public A {
public:
};
For usage:
B *b = new B();
b->Method1(); // This works, Method1 is public
b->Method4(); // This fails to compile, Method4 is inaccessible
The reason I said kind of above is because you can work around it by explicitly casting the instance of B to an A:
A *brokena = b; // This wouldn't compile because the typecast is inaccessible
A *a = (A*)b; // This however does work because you're explicitly casting
a->Method4(); // And now you can call Method4 on b...
I know, it is to late to respond. Just thought of sharing my thoughts:
Define Class A as a base class.
Have intermediate child classes A1 -> M1,M2,M3 and A2 -> M4, M5 deriving from Class A
Now, you can have
1) Class B inheriting A1
2) Class C inheriting A2
These two classes are still derived from Class A.
And also we are not breaking liskov substitution principle.
Hope, this gives clarity.
I am programming a Programme for Vacations Control for Companies (only to learn, not serious). Now I have a Abstract Class called Employee. and 4 stages of Employees.
EveryOne has it own class:
NormalWorker
SubjectAreaLeader
ChefHumanResourceOfficer
CEO
The Normal Worker can ask for Vacations, the SAL can say ok or deny the Request. If he says ok it will go to the CHRO. He can veto it or pass it. The CEO is the last Instance who can veto it.
All classes inherits the Abstract Class. The Abstract Class has a delegate called
public delegate void applyVacations(Vacation what_vacations, bool pass_or_deny)
All Subclasses have a Method
void apply(Vacation what_vacation, bool pass_or_deny)
except of the NormalWorker. And the Constructors of the subclasses shall push this apply Method to the delegate.
passing the vacation request is final for all Instances.
Example:
namespace ex
{
public abstract class A
{
public delegate void foo();
public A()
{ }
}
class B : A
{
public B()
{
A.foo = childfoo; // Does not work
}
public void childfoo()
{/* Do something*/}
}
}
Greetings
You need to create a variable of type foo and then assign childfoo to it, like so:
private foo _handler;
public B()
{
// Assign our handler for the foo delegate.
_handler = childfoo;
// Now we can call it.
_handler();
}
foo is a delegate so it's a type
in B constructor you should write
foo handler = childfoo;
then you can call handler()
namespace ex
{
public abstract class A
{
public delegate void foo();
public A()
{ }
}
class B : A
{
private foo handler;
public B()
{
handler = childfoo;
}
public void callHandlerHere()
{
handler();
}
public void childfoo()
{/* Do something*/}
}
}
this is for exemple purpose of course
B b = new B();
b.callHandlerHere() // all object inheriting A can habe a callHandlerHere function for exemple
I would like to identify the calls to members of parent class by child class.
Is it possible?
For eg:
public class base1
{
public void getvalue()
{
}
}
public class B:base1
{
}
public class C:base1
{
}
public static void main()
{
B objb=new B();
C objc=new C();
objb.getvalue();//this should display B
objc.getvalue();//this should display C
}
How can we modify getvalue() accordingly?
//Not using Overriding concepts
You can use reflection to do this:
string type = objb.GetType().Name; //will be "B"
using System;
public class Base
{
public Base()
{
}
public void M1()
{
}
public void M2()
{
}
public void M3()
{
}
}
public class Derived : Base
{
//this class should get only method 1
}
public class SecondDerived : Base
{
//this class should get only method 2 and method3
}
The requirement is : the base class contains the 3 methods M1, M2, M3.
The derived class should inherit only M1 and SecondDerived should inherit only M2 and M3.
How can this be done?
You cannot selectively inherit methods like this. A derived class automatically inherits all public methods of the base class. I suggest you to split the Base class into two classes:
public class Base1
{
public Base1()
{
}
public void M1()
{
}
}
public class Base2
{
public void M2()
{
}
public void M3()
{
}
}
public class First : Base1
public class Second : Base2
You cannot do it in this way. Inheritance implies an "IS A" relationship.
If SecondDerived would not have a M1() then it would not be compatible with a reference to a the class Base.
So maybe you shouldn't be using inheritance for whatever problem you're solving.
It is not possible to do what you want with inheritance.
It seems you have no intention of overriding, you simply want to "inherit" behavior from the base class selectively. You could do this using a "has a" relationship:
public class Base
{
internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary
public Foo Mehtod1() {...}
public Foo Mehtod2() {...}
public Foo Mehtod3() {...}
}
Then simply do the following:
class A
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method1() { return this.internalBase.Method1(); }
}
class B
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method2() { return this.internalBase.Method2(); }
public Foo Method3() { return this.internalBase.Method3(); }
}
UPDATE: A possible alternative solution is to make your Base class methods virtual and override them all in your derived classes, throwing NotSupportedExceptions in those methods that you do not want the class to make available. I don't really like this solution but it has the advantage of not loosing the polyphormism inheritance gives you which might be useful if you have some core base functionality which all derived classes will share (in your example you seem to imply they wont).
It is possible by adding Obsolete attribute
public class A
{
public virtual void M1() { }
public void M2() { }
public void M3() { }
}
public class B : A
{
[Obsolete("You can not use this", true)]
public sealed override void M1()
{
}
}
public class C : B
{
public void Test()
{
// Will show error
base.M1();
}
}
I'm trying to override an overridden method (if that makes sense!) in C#.
I have a scenario similar to the below, but when I have a breakpoint in the SampleMethod() in the "C" class it's not being hit, whilst the same breakpoint in the "B" method is being hit.
public class A
{
protected virtual void SampleMethod() {}
}
public class B : A
{
protected override void SampleMethod()
{
base.SampleMethod();
}
}
public class C : B
{
protected override void SampleMethod()
{
base.SampleMethod();
}
}
Thanks in advance!
Edit:
Ok, the context would help:
This is in the context of a composite control so class A inherits from CompositeControl and calls SampleMethod() after overriding the CreateChildControls() method.
Overriding can be performed in a chain as long as you like. The code you have shown is correct.
The only possible explanation for the behaviour you are seeing is that the object to which you are referring is actually of type B. I suggest that you double check this, and if things still don't make sense, post the other appropiate code.
Without seeing the code that calls SampleMethod, my guess would be that you have an object of type B and call SampleMethod on that.
The breakpoint is more than likely not being hit because you actually instantiated an instance of the "B" class.
Method override resolution works based on the actual runtime type of the class whose method should be called. So, if you had the following code:
C c = new C();
c.SampleMethod();
and the following:
C c = new C();
B b = (B)c;
b.SampleMethod();
both the runtime types of the class whose SampleMethod will be called is type B.
That solution works fine; although to actually use it outside the class the method is in, you need to set the access of SampleMethod to public rather than protected in all of the cases it appears, so:
public class A
{
public virtual void SampleMethod()
{
Console.WriteLine("lol");
}
}
public class B : A
{
public override void SampleMethod()
{
base.SampleMethod();
}
}
public class C : B
{
public override void SampleMethod()
{
base.SampleMethod();
}
}
for Overriding more than once in the hierarchy use something like this
// abstract class
abstract class A
{
public abstract void MethodOne();
}
// class B inherits A
class B : A
{
public override void MethodOne()
{
Console.WriteLine("From Class B");
}
}
// class C inherits B
class C : B
{
public override void MethodOne()
{
Console.WriteLine("From Class C");
}
}
// class D inherits C
class D : C
{
public override void MethodOne()
{
Console.WriteLine("From Class D");
}
}
// etc......
// class Main method Class
class MainClass
{
public static void Main()
{
B[] TestArray = new B[3];
B b1 = new B();
C c1 = new C();
D d1 = new D();
TestArray[0] = b1;
TestArray[1] = c1;
TestArray[2] = d1;
for (int i = 0; i < TestArray.Length; i++)
{
TestArray[i].MethodOne();
}
Console.ReadLine();
}
}
I did it in this code in this link
http://www.4shared.com/rar/0SG0Rklxce/OverridingMoeThanOnce.html
Method overriding is OOP feature that allows a child class to provide a specific implementation of a method that is already provided by one of its parent classes.