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
}
}
Related
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.
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.
I have many classes that have the following members/methods:
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public bool isNamed(String name) { return getName().Equals(name); }
Every time I create a new class that has a member "name", I have to rewrite all these.
Is there a way to write the methods one time and to make them apply to any class I want?
Your code can be converted to:
public String Name { get;set;}
Then you can use it as so:
nObject.Name = "Stefan";
if(nObject.Name == "Stefan"){
// do something
}else{
// do something else
}
To apply to all the classes automatically you can just make this into an interface:
public interface INameable{
public String Name {get;set;}
}
Doing this will allow you to inherit from other base classes of importance.
see here for an example
class YourClass : INameable{
//implementation
}
And now, YourClass has "Name" property automatically inserted.
You'd simply define a base class (you could make it abstract):
public abstract class Named
{
public string Name { get; set; }
}
and inherit from it:
public class Person : Named
{
}
You don't really need isNamed as in C#, it is perfectly safe to compare strings with ==.
If your class already inherits from another class which is not Named, you'll have to manually add the Name auto property or resort to simulated multiple inheritance.
Alternatively, you could create a specific modification of Named for every base class:
public abstract class NamedLifeForm : LifeForm
{
public string Name { get; set; }
}
public class Person : NamedLifeForm
{
// Person inherits both a Name and all relevant members of LifeForm
}
Another alternative would be to create a generic wrapper, Named<T>, that would have two properties: the Name and an instance of T. But that would make construction and access cumbersome, so I don't recommend it.
C# has AutoProperties just for that:
public String Name {get; set; }
This handles both the getName() and the setName() you talked about.
Usage:
To set a value: Name = "MyName;
To get a value: string theName = Name;
I'd suggest reading up on Object Oriented Programming. You can save yourself a lot of time and effort (and heckling). Here is a good primer http://www.amazon.com/Beginning-Object-Oriented-Programming-Dan-Clark/dp/1430235306
To answer your specific question, you should read about inheritance. It lets you define a "Parent" class with functions. Then you can inherit with "Child" classes and have those same functions.
http://msdn.microsoft.com/en-us/library/ms173149(v=vs.80).aspx
Here is a code example
public class PersonBase
{
private String name;
public String getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
public bool isNamed(string name)
{
return this.name.Equals(name);
}
}
public class Employee : PersonBase
{
}
Employee will now have whatever was defined by PersonBase.
As others have pointed out, you can simplify you code with properties. Also you should check for null values before using "this.name".
Here is a link to what properties are:
http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx
The simplified code example would be:
public class PersonBase
{
public String Name { get; set; }
}
public class Employee : PersonBase
{
}
I hope this helps get you pointed in the right direction for learning about these concepts.
I have a "simple" problem, and I crated an example app to illustrate. I would like the b.getName() call to return "barname", but it does not, and I'm not sure how to get this to work. I've been working in C# for years, but at the moment I feel like a newbie because this late binding problem has me stumped.
class Program
{
static void Main(string[] args)
{
bar b = new bar();
Console.WriteLine(b.getName());
Console.ReadLine();
}
}
class foo
{
string name = "fooname";
public string getName()
{
return this.name;
}
}
class bar:foo
{
string name = "barname";
}
By default your name variable is private - it sounds like you want it to be protected, so you can overwrite the value - this would work:
class foo
{
protected string name = "fooname";
public string getName()
{
return this.name;
}
}
class bar : foo
{
public bar()
{
name = "barname";
}
}
If you're not married to having a private class variable, you can accomplish this with an overridden property:
class foo
{
public virtual string Name
{
get
{
return "fooname";
}
}
}
class bar : foo
{
public override string Name
{
get
{
return "barname";
}
}
}
This isn't related to late binding. Late binding generally refers to calling a method at runtime from the name.
What your supplied code actually does is create a new variable that's in a different scope than what your base class has access to.
In order to get the desired effect, you actually need to either 1) make the base class method implementation virtual, and override the method in your child, or 2) in your base class change your variable to have a default accessibility of protected and set the value in your derived class's constructor(s).
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