Inheritance and access modifier - c#

I have the following simple C# code, but I do not understand the output.
using System;
namespace ConsoleApplication4
{
class myParent
{
public int id = 3;
private string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
private string name = "Child class private string";
}
class Program
{
static void Main(string[] args)
{
myChild c1 = new myChild();
c1.mymethod();
Console.ReadLine();
}
//Output
//Parent class private string & 3
}
}
When I invoke c1.mymethod(), why is string name in the myParent class used instead of string name in myChild class since I am invoking a method on myChild object which has a defined string name variable?
I used to believe that inheritance means simply virtually copying and pasting code from a base class to a derived class to reuse code or save key stroke. But after some research, this doesn't seem to be the case. Invoking a inherited method somehow references the base class, which might explains the output in my code.
However, I am still not clear about the inner working of inheritance. For example, I never created an instance of the base class. How should the base class method ( myParent.mymethod() ) exit?
Please help clarity my confusion and point me to some documentations.

Private is the most restrictive access for a field. It means that no other class has access to it, only the current one. Each class has its own set of private fields.
The reason why your application behaves like this is because your mymethod() member is declared public. That means that any class can call it. Since you are inheriting it, you automatically get that method in myParent. It is not copied into myparent, it is inherited. And since it is not overridden by myChild a call to myChild.mymethod() will invoke it on myParent, which accesses the only private name field it can (the one inside myParent).
If you want to inherit the name field, so it will act more like you are expecting, you need to make the field protected instead of private.
class myParent
{
public int id = 3;
protected string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
public myChild()
{
name = "Child class private string";
}
}
Now the variable in myParent is overwritten by myChild when it is instantiated. So, when you make a call to myChild.mymethod() it has access to the new value.

When I invoke c1.mymethod(), why is string name in the myParent class used instead of string name in myChild class since I am invoking a method on myChild object which has a defined string name variable?
The method c1.mymethod() is defined only in myParent class. Therefore, when you invoke the method, it is going to use the name found in closest proximity to that method. In other words, it will first search the myParent class for that variable and if found it will use it.
If you did this however (make myMethod virtual and override it in the myChild):
class myParent
{
public int id = 3;
private string name = "Parent class private string";
public virtual void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
private string name = "Child class private string";
public override void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
Then it will use the name variable from myChild class since that is the closest one.
You will run into a similar situation if you did this:
public class Person
{
private string name = "John";
public Person(string name)
{
// The parameter is named `name` and the field is named `name`
// so the compiler is going to choose the closest variable.
// In this case, it will assign `name` parameter to itself.
// Visual Studio is nice, in this case, to give you a warning but
// your code will compile and the compiler will just assign `name`
// to `name`
name = name;
// If you did this: this.name = name;
// then the private field will be assigned the value of the parameter
}
}

From C# specification:
Here is how Inhertiance is defined:
Inheritance means that a class implicitly contains all members of its
direct base class type, except for the instance constructors,
destructors and static constructors of the base class.
Now about extending base class.
A derived class extends its direct base class. A derived class can add
new members to those it inherits, but it cannot remove the definition
of an inherited member.
In other word you can extended base class by adding new definitions (or overriding existing ones), but you can't remove any.
And to get it more cleaner:
A derived class can hide (§3.7.1.2) inherited members by declaring new
members with the same name or signature. Note however that hiding an
inherited member does not remove that member—it merely makes that
member inaccessible directly through the derived class.
What you do in your derived class is called hiding and as you can see from quote it doesnt remove that member.
And because in your MyParent class you are using name field defined in same class it will always print what it does. For changing this behaviour you should have look at Virtual properties.

Your new field name in the myChild class does not make the inherited field name from the base class go away! It just hides in. OK, it was hidden already because it was private, but introducing a new field in the derived class still does not make the hidden field go away.
If you want a name that is read-only, you can use a protected virtual property with no set accessor, and override it in the deriving class:
class myParent
{
public int id = 3;
protected virtual string name => "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
protected override string name => "Child class private string";
}
If you want to keep it as a private field, offer a constructor that the deriving class can chain:
class myParent
{
public int id = 3;
private string name;
public myParent() : this("Parent class private string")
{
}
protected myParent(string name)
{
this.name = name;
}
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
public myChild() : base("Child class private string")
{
}
}

This happens because you have used a method inside the parent's context. As you have not overridden myMethod() it will get executed using the private field in that parent's context. if you use method overriding here when you want to get the name of the child's context you can create a child object.
namespace ConsoleApplication2
{
class myParent
{
public int id = 3;
private string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
private string name = "Child class private string";
public new void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class Program
{
static void Main(string[] args)
{
myChild c1 = new myChild();
c1.mymethod();
Console.ReadLine();
}
//Output
//Parent class private string & 3
}
}
If you want to get the name of the parent's context you can get that using a parent object.
static void Main(string[] args)
{
myParent c1 = new myChild();
c1.mymethod();
Console.ReadLine();
}

If you want to access a field in the derived class, you can define it as protected.
class myParent
{
public int id = 3;
protected string name = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
and set it in the child constructor
class myChild : myParent
{
public myChild()
{
name = "Child class private string";
}
}
Alternatively you can use the virtual/override keyworkds if you define name as a property { get; set; }
class myParent
{
public int id = 3;
protected virtual string name { get; set; } = "Parent class private string";
public void mymethod()
{
Console.WriteLine("{0} & {1}", name, id);
}
}
class myChild : myParent
{
protected override string name { get; set; } = "Child class private string";
}
I never created an instance of the base class.
It is created internally when you instantiate the derived class.
When I invoke c1.mymethod(), why is string name in the myParent class used instead of string name in myChild class since I am invoking a method on myChild object which has a defined string name variable?
Basically your original code is equivalent - in terms of its output - to the above case of a virtual name with a new keyword in the derived class
class myChild : myParent
{
new string name { get; set; } = "Child class private string";
}
In that case, the parent's method will display the parent's name, since the child's name is now a different, new variable and it's no longer the one used in the parent's method.

Related

String is not being assigned?

using System;
public class Shurli
{
public class MyTest
{
private string name = "qwe"; // the name field
public string Name // the Name property
{
get
{
return this.name;
}
}
}
public class yourJs : MyTest
{
private string name = "chah";
}
static void Main()
{
var met = new yourJs();
string acer = met.Name;
Console.WriteLine(acer);
}
}
I fully expected the output to be "chah", but the output was "qwe". I've been trying to figure this since a few hours ago but still haven't figured it out. Can someone please help?
Visual studio gives the warning: "The field 'Shurli.yourJs.name' is assigned but its value is never used"
The name fields in the MyTest and yourJs classes are in two different scopes - they are completely independent from one another, even though they have the same name.
To make the code work the way you describe, name should be declared only in the base class as a protected field and then assigned in the child class.
public class MyTest
{
protected string name = "qwe"; // the name field
public string Name // the Name property
{
get
{
return this.name;
}
}
}
public class yourJs : MyTest
{
public yourJs()
{
name = "chah";
}
}
The met.Name will refer to Name the inherited property in MyTest as yourJs contains only name which is a private member and could not be access directed form outside the class. Remember that C# is case sensitive and name and Name are two different variables.
If you want to access the yourJs name private data member then you need to make it public or access its values to some public method/property.
Just to check if you can access the Member name in yourJs we make it public.
public class yourJs : MyTest
{
public string name = "chah";
}
static void Main()
{
var met = new yourJs();
string acer = met.name;
Console.WriteLine(acer);
}
Edit based on comments, about the relation between private members and public properties.
Properties
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily and
still helps promote the safety and flexibility of methods.
In memory a yourJs object would have one Name property and two instance fields named name (one inherited from its base class MyTest and one declared in the derived class itself).
The field name declared in the derived type hides the inherited field.
The inherited property Name will always reference the inherited field name no matter what access modifier you use for the fields.
You have three options to get the desired output:
Option 1: As mentioned by BJ Myers, the name field should be declared only in the base class and then assigned in the derived class.
Option 2: Declare a new property with the same name in the derived class (hiding the inherited property).
public class MyTest
{
private string name = "qwe";
public string Name { get { return name; } }
}
public class yourJs : MyTest
{
private string name = "chah";
public new string Name { get { return name; } }
}
Option 3: Override the inherited property to use the field declared in the derived class.
public class MyTest
{
private string name = "qwe";
public virtual string Name { get { return name; } }
}
public class yourJs : MyTest
{
private string name = "chah";
public override string Name { get { return name; } }
}
private string name = "chah"; will declare a new field within the class yourJs.
Therefore you have two fields called name - one in MyTest and one on yourJs.
AND: The property Name returns the field MyTest.name, because Name is declared in MyTest.
This has nothing to do with the private modifier - the problem is the introduction of a second name field.
If you want to change the value of name in yourJs, you have to declare it different:
public class MyTest {
protected string name = "qwe"; // This is the ONLY name field, visible by inherited classes
public string Name {
get { return this.name; }
}
}
public class yourJs: MyTest {
public yourJs() {
name = "chah"; // Change the value of MyTest.name
base.name = "chah"; // Same as above, but explicit useage of base class MyTest
}
}

Property returns string from base class while member returns string from inherited class?

Here is the program:
public class Program
{
static void Main()
{
MyInheritedClass InheritInstance = new MyInheritedClass();
Console.WriteLine(InheritInstance.name); // the name field
}
}
public class MyClass
{
public string name= "I am the Base"; // the name field
public string Name // the Name property
{
get
{
return this.name;
}
}
}
public class MyInheritedClass : MyClass
{
new public string name= "I inherit Base";
}
This works as expected. the output is: "I inherit Base"
Now if I change Console.WriteLine(InheritInstance.name); // the name field to Console.WriteLine(InheritInstance.Name); // the name property, it magically outputs: "I am Base"
I am baffled as to WHY this happens? I called the Name property of MyInheritedClass, how did the Name property of MyClass get called? Or maybe the Name property of MyClass is called and it somehow magically accesses the name field of MyClass?
Now if I change Console.WriteLine(InheritInstance.name); // the name
field to Console.WriteLine(InheritInstance.Name); // the name
property, it magically outputs: "I am Base"
This happens because MyClass is unaware of the new operator in your derived class. As far as it knows, it only has one string field called Name, which is declared in the base class. When the property has the retrieve it via the getter, it goes to the name declared there.
As the docs say:
When used as a declaration modifier, the new keyword explicitly hides
a member that is inherited from a base class. When you hide an
inherited member, the derived version of the member replaces the base
class version
If you want to override that behavior, you can declare name as virtual:
public class MyClass
{
public string name = "I am the Base";
public virtual string Name { get { return this.name; } }
}
public class MyInheritedClass : MyClass
{
public new string name = "I inherit Base";
public override string Name { get { return this.name } };
}
Note this looks and feels redundant. You can avoid that by declaring a single virtual property:
public class MyClass
{
public virtual string Name { get { return "I am base" } }
}
public class MyInheritedClass : MyClass
{
public override string Name { get { return "I am derived" } };
}
It calls your base class property because the Name property is defined only in the base class. This is the default and simplest behavior of inheritance. You can access properties from the base class.
When you need control over a property from the Base class you can use the override or new constructs to define your desired behavior for the property in the Child class.

How to Get Base Class Instance from a Derived Class

I don't know if this is possible, but I am trying to get the Base Class instance from a Derived Class. In C#, I can use the base keyword to access properties and methods of the Base Class (of course), but I want to use base itself. Attempting to do so results in a "Use of keyword 'base' is not valid in this context" error.
Example Code
public class SuperParent
{
public int SPID;
public SuperParent()
{
}
}
public class SubChild : SuperParent
{
public SubChild(int pSPID)
{
base.SPID = pSPID;
}
public int BaseSPID
{
get
{
SuperParent sp = base;
return sp.SPID;
}
}
}
If you're working with an instance of the derived class, there is no base instance.
An example:
class A
{
public void Foo() { ... }
}
class B : A
{
public void Bar() { ... }
}
What is not possible within B:
public void Bar()
{
// Use of keyword base not valid in this context
var baseOfThis = base;
}
You can do something like this:
public void Bar()
{
base.Foo();
}
And you can add another method like
public A GetBase()
{
return (A)this;
}
And then you can
public void Bar()
{
var baseOfThis = GetBase();
// equal to:
baseOfThis = (A)this;
}
So this GetBase() method is probably what you want.
The punchline is: If you have an instance of B, it inherits all properties and the non-overriden behaviour of A, but it does not consist of an instance of B which holds an (hidden but automatic) reference to an instance of A. You can cast your B instance to A, but it remains to be an instance of B.
Well you not provide code for your question, but i supsect you want something like
class Base
{
public virtual void Foo()
{
Console.WriteLine("base");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("derived");
}
//// bad
//public Base MyBase
//{
// get
// {
// return base; // Use of keyword 'base' is not valid in this context
// }
//}
// work but...
public Base MyBase
{
get
{
return (Base)this;
}
}
}
But keep in mind that MyBase is really of type Derived
new Derived().MyBase.Foo(); // output "derived"
the problem hasn't been explained as clearly as it could. however, typically, you may be better to use an abstract base class and methods and then override the required methods. you can then use the base.method as required in this case (otherwise you'll have just spun up an instance of the derived class).
public abstract class foo {
public virtual void bar(){..}
}
public class footwo : foo {
public override void bar(){
// do somethng else OR:
return base.bar();
}
}
}
The derived instance IS the base instance. It's just one object instance in memory.
example:
public class A : B
{
}
var thing = new A();
thing is an instance of an A, and is also an instance of a B.
You could for example, write this line:
B thing2 = thing;
Point 1: if you want to create the base class instance within child class than it does not worth. You already have public things accessible in child.
Point 2: If you have initialized child class and now want to get base class "instance" then how can you get that if it's not initialized(Because now the base class instance is not present in the physical memory, and there is just child class instance there)?
I interpreted what they were asking a bit differently than the other answers here so I figured I would offer my $0.02.
// Create a "Parent" class that has some attributes.
public class Parent
{
public string attribute_one { get; set; }
public string attribute_two { get; set; }
public string attribute_three { get; set; }
}
// Define a class called "Child" that inherits the
// attributes of the "Parent" class.
public class Child : Parent
{
public string attribute_four { get; set; }
public string attribute_five { get; set; }
public string attribute_six { get; set; }
}
// Create a new instance of the "Child" class with
// all attributes of the base and derived classes.
Child child = new Child {
attribute_one = "interesting";
attribute_two = "strings";
attribute_three = "to";
attribute_four = "put";
attribute_five = "all";
attribute_six = "together";
};
// Create an instance of the base class that we will
// populate with the derived class attributes.
Parent parent = new Parent();
// Using reflection we are able to get the attributes
// of the base class from the existing derived class.
foreach(PropertyInfo property in child.GetType().BaseType.GetProperties())
{
// Set the values in the base class using the ones
// that were set in the derived class above.
property.SetValue(parent, property.GetValue(child));
}
The result is a new object populated with the base class properties of the child class.
class Parent
{
private Parent _parent;
public Parent()
{
_parent = this;
}
protected Parent GetParent()
{
return _parent;
}
}
class Child : Parent
{
private Parent _parent;
public Child()
{
_parent = base.GetParent();
}
}

C#, access child properties from parent reference?

public void GetProps(Parent p){
// want to access lots of child properties here
string childProp1 = p.prop1;
bool childProp2 = p.prop2;
bool childProp3 = p.prop3;
}
However compiler complains that
"Parent does not contain definition prop1"
The function would take in different subtypes of Class Parent.
All the subclasses have this
public override string prop1 { get; set; }
Is there a way of accomplishing this?
EDIT:
To make the question clearer
I current have a giant if-elseif where i do something like
if(p is Child0){
Child0 ch = p as Child0;
// want to access lots of child properties here
string childProp1 = ch.prop1;
bool childProp2 = ch.prop2;
bool childProp3 = ch.prop3;
}else if(p is Child1){
Child1 ch = p as Child1;
// want to access lots of child properties here
string childProp1 = ch.prop1;
bool childProp2 = ch.prop2;
bool childProp3 = ch.prop3;
}else if(...// and many more
Now I wanted to remove all the redundant code and make one function that can handle all this.
If all child classes need to have the properties (but with different implementations), you should declare them as abstract properties in the base class (Parent), then implement them in the child classes.
If some derived classes won't have those properties, then what would you expect your current GetProps to do?
EDIT: If you're using C# 4 and you definitely can't get a better class design (where the parent class declares the property) you could use dynamic typing:
public void GetProps(Parent p) {
dynamic d = p;
string childProp1 = d.prop1;
bool childProp2 = d.prop2;
bool childProp3 = d.prop3;
// ...
}
I'd treat this as a last resort though...
The solution in case someone need it, it is just to cast the class you receive as a reference as follows:
public void GetProps(Parent p){
..
string childProp1 = ((ChildClass)p).prop1;
...
}
As I understood from your question, you want to access Children Class members from object of Parent Class.
This behavior is not allowed in OOP.
One way can be as suggested by Jon Skeet to create a Abstract base class and implement the required members in Children Classes.
Other way round can be to assign the required values to members of base class in derived class constructor using base construct. I do not know this will solve your problem or not. But Consider the following snippet for example:
public class BaseClass
{
public string FirstName = "Base Class";
public string LastName = "Base Class";
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
base.LastName = "Derived Class";
}
}
internal class Tester
{
private static void Main(string[] args)
{
BaseClass objBaseClass = new BaseClass();
Console.WriteLine("First Name : " + objBaseClass.FirstName);
Console.WriteLine("Last Name : " + objBaseClass.LastName);
DerivedClass objDerivedClass = new DerivedClass();
Console.WriteLine("First Name : " + objDerivedClass.FirstName);
Console.WriteLine("Last Name : " + objDerivedClass.LastName);
BaseClass objBaseDerivedClass = new DerivedClass();
Console.WriteLine("First Name : " + objBaseDerivedClass.FirstName);
Console.WriteLine("Last Name : " + objBaseDerivedClass.LastName);
Console.ReadKey();
}
}
O/P
First Name : Base Class
Last Name : Base Class
First Name : Base Class
Last Name : Derived Class
First Name : Base Class
Last Name : Derived Class
Let me know, if it helps out.
If the property is defined in an intermediate class between parent and child and you don't have a reference to that intermediate class at design time then you could use reflection to get the property. But it sounds like you should be using the most relevant sub parent instead of simply parent.
If I understood you correctly (- I'm assuming Parent is a base class from which Child0 Child1 etc inherit.) – you're just missing a declaration of prop1 in the parent. It won't get in the way, it will simply be overridden.
Check out this example (which returns "child string") and note that child is passed to a method that expects a ParentClass instance.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ChildClass child = new ChildClass();
Text = ParentClass.mymethod(child);
}
}
class ParentClass
{
public virtual string s { get { return "parent string"; } }
public static string mymethod(ParentClass parent)
{
return parent.s;
}
}
class ChildClass : ParentClass
{
public override string s { get { return "child string"; } }
}

Populate base class along with child class?

I have a need where I have to add some new fields to an existing class along with all its existing fields/attributes.
So whenever my derived class is filled by DAL, I will be filling all fields of base class as well. Currently, I am doing it like this but not sure this is the right way ? Please give me an example. Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
public class Employee
{
private int _id;
private int _name;
public int ID
{
set { _id=value;}
get { return _id;}
}
public int Name
{
set { _name=value;}
get { return _name;}
}
protected void SetName ()
{
_name=value;
}
protected void SetID()
{
_id=value;
}
}
public class EmployeeWithDepartmentName:Employee
{
private string _deptName;
public string DeptName
{
set { _deptName=value; }
}
public setBaseEmpName()
{
base.SetName();
}
public setBaseID()
{
base.SetID();
}
}
Everything in a base class can automagically be accessed from derived classes without doiing anything, just use the property/method name directly.
public class MyBase
{
public string UserName {get;set;}
}
public class MyClass : MyBase
{
public void DoSomething()
{
Console.WriteLine("UserName: {0}", UserName);
UserName = "Anders";
}
}
You can also do this:
MyClass myClass = new MyClass();
myClass.UserName = "Rune";
Protected means that only derived classes can access the property/method. Public means that everyone can access the properties/methods.
Also I am not sure whether the base class object will be a new one each time a derived class is initialized ?
It's not two objects, it's one object created from two different classes (that's how inheritance works).
Read this article about inheritance: http://www.csharp-station.com/Tutorials/lesson08.aspx

Categories