we have the classes:
class A
{
}
class B:A
{
public void metod(){}
}
and
static class C
{
static void met(B clas)
{
A test = clas as B;
// is it any way to get method "metod " from B via test?
}
}
I know that this look like nonsense but the idea is right, I cannot make B object in C class.
Child can access parent through base. For e.g.
base.SomeMethod();
because when inheriting child knows who parent is and that parent class becomes base
but there is no keyword like child because base does not know which class will inherit it.
A child can have a single parent but a parent can have one or more child.
You need to convert it back like this and than you can access
Base derivedInstance = new Derived();
Derived child= (Derived)derivedInstance;
child.Callmethod();
in short
A test = clas as B;
((B)test).method();
You can cast test to B, or simply use the variable declared as B in the first place:
((B)test).metod();
or
clas.metod();
class A
{
public virtual void method(){}
}
class B:A
{
public override void method(){}
}
and
static class C
{
static void met(B clas)
{
A test = clas as B;
test.method(); //this may be what you want?
}
}
Related
Base Class
class TestBase
{
protected int a;
protected int b;
public TestBase(int i)
{
a = i;
}
protected TestBase()
{
}
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.Update("Hello World ");
}
Child Class
class TestChild:TestBase
{
private string msg;
public void Update (string s)
{
msg = s+ a.ToString();
Console.WriteLine("msg=" + msg);
}
}
Calling
private void btnTest_Click(object sender, EventArgs e)
{
TestBase t = new TestBase(1);
t.Update(100);
}
Result
Hello World 0
Problem
I was hoping to get Hello World 100. Obviously the child class did not access base class variable int a. how can I do that?
First of all, it's not clear what you're trying to accomplish.
There are many problems with this code. First, you should not be creating an instance of TestChild inside a TestBase class method. If you create an instance of TestBase inside btnTest_Click, then there is no way you'll be able to access any of TestChild's methods or data (except that you are creating an instance of TestChild inside TestBase which is bad practice).
The purpose of inheritance is usually to extend the data/methods for a base class, not to use an inherited class inside a base class. Also, with a set of inherited classes, you can achieve polymorphism which is another core principle of Object Oriented Programming. You should get a better understanding of these principles and then the code will start making more sense.
The object you created in TestBtn_Click has nothing to do with the object you created in TestBase.Update. They are two different objects so each have their own a field with different values.
To produce the output you expect, you need to set child.a to this.a in Update:
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.a = this.a;
child.Update("Hello World ");
}
The important thing to understand here is that inheritance does not affect objects. Inheritance only affects classes. The base class members will also be present in the subclass. That's it. Even though objA's type inherits from objB, they are unrelated unless they are the same object.
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.Update("Hello World ");
}
This is where you are assigning value to variable a, and later you instantiated another instance of TestChild class which is different.
After this instantiation you have to assign the value like
TestChild child = new TestChild();
child.a = i;
child.Update("Hello World ");
Then you shall get your desired result
The child object inside your TestBase doesn't know where is he placed. It doesn't know it is inside of a class.
When you create the child you also create a totally different TestBase object which is not the same as what contains the child. When you create that object a will be initialized to a default value which is 0 in this case.
If you would like to carry the value of a to an other object you should give it to it. For example through the constructor.
Call like this:
TestChild child = new TestChild(a);
Make a constructor like this:
public TestChild(int x) : base(x){}
Unfortunately your concept bleeding from everywhere so it will not work in this form. I recommend to study inheritance more.
This is how to use inheritance:
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Dalmata", "Fuffy", 7);
}
}
class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public Animal(string name, int age)
{
Name = name;
Age = age;
}
}
class Dog : Animal
{
public string Race { get; set; }
public Dog(string race, string name, int age) : base(name, age)
{
Race = race;
}
}
This way, you will acess Name and Age too, even if they are declared in Animal.
you should call your base class this way
class BaseClass
{
int a;
int b;
protected BaseClass()
{ }
protected BaseClass(int i)
{
a = i;
}
protected void Update(int i)
{
a = i;
Console.Write("Hello World ");
}
}
class TestChild : BaseClass
{
public TestChild(int i) : base(i) //send your constuctor to your base class
{ }
public TestChild()
{ }
public void Update(int i)
{
base.Update(i);
Console.Write(i.ToString());
}
}
private void btnTest_Click(object sender, EventArgs e)
{
TestChild t = new TestChild(); // create instance as your child
t.Update(100);
}
create your object as your child class then call your method and let it call your base class
also if wanna access a or b in base class from your child
public int a;
public it so you can access it from instance you created
protected will allow only inside child class to access to it
If you'd like to get the expected result, put a static modifier front of a and/or b variables, like this:
static protected int a;
static protected int b;
After this, if you push that button it will write out:
msg=Hello World 100
Here it is:
abstract class IA
{
public virtual void ChangePropertyOfAIChild()
{
b.value = true;
}
}
...
class B:IA
{
bool value;
}
class C:IA
{
bool value;
}
....
///main
IA newBInstance = new B();
newBInstance.ChangePropertyOfAIChild();
IA newCInstance = new C();
newCInstance .ChangePropertyOfAIChild();
/////
What would be a proper way of calliing an already implememnted function in a child's class from the base abstract class and changing it's value?
Thanks!
As #Camilo Terevinto pointed out, you heirarchy is wrong. try:
public abstract class IA
{
public bool value;
public virtual void ChangePropertyOfAIChild()
{
value = true;
}
}
public class B : IA
{ }
public class C : IA
{ }
// in main
IA newBInstance = new B();
newBInstance.ChangePropertyOfAIChild();
IA newCInstance = new C();
newCInstance.ChangePropertyOfAIChild();
///
Your sample code had the base abstract class trying to change the value of a field in a class it doesn't know about:
(b.value = true)
For the base class to be able to do this, the field needs to be declared inside the base class.
I believe you have't got your inheritance quite right.
If this is your class implementation:
public abstract class IA
{
}
public class B : IA
{
public bool value;
}
public class C : IA
{
public bool value;
}
And then if you create an instance of IA like so:
IA newBInstance = new B();
Then compiler goes ahead and creates an instance of IA. Since your IA does NOT have a property called value, you cannot access it.
You have two options, either use the method suggested by CodexNZ in the previous reply, or simply cast your newInstance to B and directly set value. Like this:
IA newBInstance = new B();
((B)newBInstance).value = true;
However this is counter intuitive since if you can do that you might as well create an instance of B in the first place. So I recommend the previous method. This is more to explain why your logic doesn't work.
Please refer to a tutorial like this to learn more. There are tons of more resources on the internet.
For example I have two classes, Base and Derived as shown below:
class Base
{
public string Name { get; set; }
public Base()
{
}
}
class Derived : Base
{
public Derived(Base b)
{
base = b; // doesn't compile, but is there any way to do something similar?
}
}
So that they behave like this:
Base b = new Base();
b.Name = "Bob";
Derived d = new Derived(b);
d.Name = "John";
// b.Name is now "John" also
Is this possible? I guess one way would be to keep the Base b reference in Derived and override Derived.Name to point to b.Name? Is there an easier way though, for example if I have like 50 properties to override?
class Derived : Base
{
Base b;
public override string Name
{
get { return b.Name; }
set { b.Name = value; }
}
public Derived(Base b)
{
this.b = b;
}
}
EDIT:
I guess another way to say it would be that I am creating a sort of wrapper for class Base. I am given an object of type Base and want to wrap it with class Derived but still keep Base's original public properties/methods/etc. I'm not sure if that makes it more clear or not.
I think from what you seem to be hinting at ( atleast from the edit - "I am creating a sort of wrapper for class Base"), you are looking at using the Decorator pattern:
http://en.wikipedia.org/wiki/Decorator_pattern
The decorator pattern can be used to extend (decorate) the
functionality of a certain object at run-time, independently of other
instances of the same class, provided some groundwork is done at
design time. This is achieved by designing a new decorator class that
wraps the original class.
Guess I'm confused
public BaseClass
{
public string Name { get; set; }
}
public DerivedClass : BaseClass
{
}
DerivedClass d = new DerivedClass();
d.Name = "Test";
BaseClass b = d as BaseClass;
print b.Name;
Output:
Test
The derived object inherits the methods, properties, fields and constructors(to some extend) of the base class, why override them when you can just use them.
Have you heard of the Decorator Pattern? http://en.wikipedia.org/wiki/Decorator_pattern
It's a way of dynamically modifying behavior at runtime by wrapping instances of classes within themselves like Russian Dolls. They all implement the same interface so to the user of the class the wrapped and unwrapped versions appear the same.
Interface IDecorator{
public void foo();
}
public class OuterDecorator:IDecorator{
private IDecorator _inner;
public OuterDecorator(IDecorator inner){
this.__inner = inner;
}
public void foo(){
this._inner.foo();
Console.Writeline("Hello from outer");
}
}
public class InnerDecorator:IDecorator{
public void foo(){
Console.Writeline("Hello from inner");
}
}
You can make a static function be a Factory Method.
public static IDecorator GetDecorator(){
var inner = new InnerDecorator();
var outer = new OuterDecorator(inner);
return outer;
}
And use it like so. The advantage is that the consumer of this class doesn't need to know the implementation details of the concrete class doing the work. Since both InnerDecorator and OuterDecorator implement the same interface they can be used interchangeably.
IDecorator d = OuterDecorator.GetDecorator();
d.foo();
//Output
//Hello from Inner
//Hello from Outer
here's some more information on the decorator pattern:
HeadFirst Design Patterns - start here
DoFactory
class Parent
{
public int GetNo()
{
return 1;
}
}
class Child : Parent
{
public Child()
{
}
public int GetNo()
{
return 2;
}
}
Parent p = new Child();
p.GetNo();
But it calls Base.GetNo(). I know if I use virutal in base it will call Child.GetNo()
But i can't use virutal in Base becuase i have to derive my class from base which is already distributed in DLL.So there's no way i can modify the existing functions of base class.
Any sugguestions are valued.
Thanks
You can cast it:
((Child)p).GetNo();
or
if(p is Child)
(p as Child).GetNo();
I have just come here so i could find a solution that doesn't use casts, but since i didn't find it here is one.
Maybe it can be of help for someone.
abstract class Parent
{
public int GetNo()
{
return GetNoImpl();
}
protected abstract int GetNoImpl();
}
class Child : Parent
{
public Child()
{
}
protected override int GetNoImpl();
{
return 2;
}
}
Parent p = new Child();
p.GetNo();
Note: the parent class is abstract.
You can force this with an explicit cast e.g.
((Child)p).GetNo();
Or you can use hiding e.g.
public new int GetNo()
{
return 2;
}
Though I think the latter only gets called if the variable is typed to the class that hides the method.
If you really need to override a method properly and it's from a compiled DLL consider getting in touch with the developers to see whether they can make the method virtual (and if not why) or if an open source project just get the source code and modify it yourself.
Without virtual declared on the method, the base method will always be called because you declared your variable as Parent. If you can't append virtual to the base class, then you can only either declare the variable as Child, or cast it to Child and call your GetNo method:
Child p = new Child();
p.GetNo();
Or:
Parent p = new Child();
((Child)p).GetNo();
Let's say I have a classes, like that:
class A
{
public static int Count()
}
class B : A
{
}
class C : A
{
}
How can I hide this static method for class B but not for C?
You can't, basically. Heck, if it's public then anyone can call it.
You could make it protected which would allow it to be called from within B or C but not elsewhere... but you still couldn't differentiate between B and C.
You could do it by creating another class, let's call it Special, that inherits A. Then you would make C inherit from Special and B inherit from A. Also, you would have the static method protected, that means only classes that inherited Special will have access to it.
class A
{
}
class Special : A
{
protected static int Count()
}
class B : A
{
}
class C : Special
{
}
The only solution would be to change your class hierarchy. It's not worth the hassle and WTF moments you will get in code reviews it if you ask me.
class ABase
{
}
class A
{
public static int Count()
}
class B : ABase
{
}
class C : ABase
{
}