There are two clarifications I need which I am trying to understand.
I see that, I can access the variable "i" using "base" keyword as well as using the object. Is there any difference of it? I think, creation of object is memory consuming and hence we use base keyword itself to call base class members in derived class?
When to use this.i and base .i and object.i?
class Program
{
public Program()
{
i = 20;
}
public readonly int i = 10;
}
class C : Program
{
public C() : base()
{
//base.i = 20;
}
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 20
Console.WriteLine(c.i);//prints 20
Console.WriteLine(this.i); //Also prints 20 :D
}
static void Main()
{
C c = new C();
c.Display();
Console.ReadLine();
}
I tried to accept one answer as that helped me understand few things. But still, my question "the difference ans usage of 3 different styles at my context and in other contexts" is not clear. So please care to share your thoughts on this, I would appreciate it. I am sure there are millions like me who try to understand this :)
As for 1) You can use both to access the property as the sub class has extended it. There will only be a difference if you override that in the sub class or if you decide to create a field with the same name in your sub class.
EDIT:
To override it, you can make it a virtual property in the base class
public class Base
{
public virtual int i {get; set;}
}
public class Sub : Base
{
public override int i { get; set; }
}
Problem 2 : Your StackOverflow
you care creating a new instance of Program every time you create a new instance of Program it seems to be an infinite loop.
class Program
{
Program p = new Program(); // <-- this line here
In your case there is no difference. Difference comes when you have field with same name in base class and derived class(typically we don't have it).
class Program
{
public int i = 10;
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//prints 10
Console.WriteLine(c.i);//prints 20
}
}
base keyword refers to base class, so base.i refers to "member named i" in base class.
Also worth noting that when you access a member with base keyword and it doesn't exist compiler will produce an error.
class Program
{
//public int i = 10; //No field named i
}
class C : Program
{
public int i = 20;
public void Display()
{
C c = new C();
Console.WriteLine(base.i);//Compile time error here
Console.WriteLine(c.i);//this refers to C.i field
}
}
Answer for Question 1
Base you can use when you want to refer you prent class from the child class.
Example :
public class A
{
public int i {get;set;}
}
public class B:A
{
publi void readvalueofi()
{ Console.Writeln(base.i); }
}
This also useful when you override method of parent and want to call parent method from child
Example :
public class Parent
{
public virtual void Print()
{
Console.WriteLine("Print in Parent");
}
}
public class Child : Parent
{
public override void Print()
{
base.Print();
Console.WriteLine("Print in Child");
}
}
Answer for Question 2 :
Reason for StackOverflow Exception
You're creating an private instance of Program when Program is created so this is sort of an endless loop:
your first create Program instance. When this instance is creating it creates a new instance of Program. This instance also creates an instance of Programand again, and again etc.
So basially it creates infinite loop over here.
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
I read some material about the "new" keyword for method overhiding in C#. However I still don't see the significant purpose of that "new" keyword except to fix the warning "CS0108 C# hides inherited member. Use the new keyword if hiding was intended." in Visual Studio.
For sample:
class ClassA
{
public void printInfo()
{
Console.WriteLine("I'm A");
}
}
Test Case 1:
class ClassB : ClassA
{
public void printInfo()
{
Console.WriteLine("I'm B");
}
}
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
a.printInfo();
ClassB b = new ClassB();
b.printInfo();
ClassA ab = new ClassB();
ab.printInfo();
Console.ReadKey();
}
}
And
Test Case 2 with "new" keyword:
class ClassB : ClassA
{
public new void printInfo()
{
Console.WriteLine("I'm B");
}
}
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
a.printInfo();
ClassB b = new ClassB();
b.printInfo();
ClassA ab = new ClassB();
ab.printInfo();
Console.ReadKey();
}
}
They both have the same output:
I'm A
I'm B
I'm A
The difference is that "new" keyword fixes the warning.
Could someone show me more samples for the helpfulness of the "new" keyword here ?
There is no difference between both codes. The compiler is simply warning you that you might be unaware of the fact that you are hiding A.printInfo and it's simply drawing your attention to it.
In large codebases where maybe you don't even own A it's easy to write a method in a derived class that has the same signature as an existing method in the base class.
With the keyword new you get three immediate advantages:
You are informing the compiler that you are aware of the fact and you are intentionally hiding a method/property.
You are making it clear to anyone reviewing or mantaining your code in the future that you are hiding a method/property.
Your code actually compiles if warnings are set to be treated as compile time errors, something that is advisable and commonly the case in any decent quality coding environment.
MSDN has a good article about when to use Override and New keywords took a look at it
Knowing When to Use Override and New Keywords
The main idea is that when you are writing public new void function() you are telling the compiler that you know that this method is being hidden by the method from baseclass and the warning is disappearing. Now you will be able to use this method from instance of the derived class and the base method from instance of the base class or boxed to the base class.
Both your samples of code give the same result because the addition of the new modifier doesn't change the output of the compiler - it just gets rid of the compiler warning CS0108. Without the new, the compiler is adding it for you:
This warning informs you that you should use new; the variable is declared as if new had been used in the declaration.
That said, hiding with new and overriding do not have the same effect as each other, due to polymorphism.
Consider the following case (try it online):
Main class:
public class Program
{
public static void Main()
{
Developer developer = new Developer();
PrintSalaryWithHiding(developer);
PrintSalaryWithOverriding(developer);
}
public static void PrintSalaryWithHiding(Employee employee)
{
Console.WriteLine("Salary (with hiding): " + employee.SalaryWithHiding);
}
public static void PrintSalaryWithOverriding(Employee employee)
{
Console.WriteLine("Salary (with overriding): " + employee.SalaryWithOverriding);
}
}
Base class (note that SalaryWithHiding is not virtual but SalaryWithOverriding is):
public abstract class Employee
{
public int SalaryWithHiding
{
get
{
return 10000;
}
}
public virtual int SalaryWithOverriding
{
get
{
return 10000;
}
}
}
Derived class (note the new before SalaryWithHiding and the override before SalaryWithOverriding):
public class Developer : Employee
{
public new int SalaryWithHiding
{
get
{
return 50000;
}
}
public override int SalaryWithOverriding
{
get
{
return 50000;
}
}
}
The result of this is
Salary (with hiding): 10000
Salary (with overriding): 50000
Why?
It's because the new keyword tells the compiler that if you have a instance of a Developer, declared as a Developer, calling the SalaryWithHiding method will call the one in the Developer class instead of the one in the Employee class (i.e. it hides it).
When you have a instance of a Developer, declared as an Employee, calling the SalaryWithHiding method calls the one in the Employee class.
You can see this in the following cut-down example (try it online):
Main class:
public class Program
{
public static void Main()
{
Developer developer = new Developer();
Console.WriteLine("Developer salary when declared as developer: " + developer.SalaryWithHiding);
// these are the same object!
Employee employee = developer;
Console.WriteLine("Developer salary when declared as employee: " + employee.SalaryWithHiding);
}
}
Employee:
public abstract class Employee
{
public int SalaryWithHiding
{
get
{
return 10000;
}
}
}
Developer:
public class Developer : Employee
{
public new int SalaryWithHiding
{
get
{
return 50000;
}
}
}
The result is:
Developer salary when declared as developer: 50000
Developer salary when declared as employee: 10000
Summary
In general, I would say you should only use the new modifier if you know what you are doing, as it breaks polymorphism: as you saw in your own example, when you had
ClassA ab = new ClassB();
ab.printInfo();
it called the method in ClassA as though you hadn't declared a separate method in ClassB which have a different result. That can be very confusing. You would have been much better off making the method in the base virtual and overriding it in the derived class instead, unless you wanted that behaviour for some reason. In my (contrived) example using new to hide a method resulted in an incorrect salary!
I have read an article regarding the new keyword. It says it is used to hide methods. This is example they give:
using System;
namespace ConsoleApplication3
{
class SampleA
{
public void Show()
{
Console.WriteLine("Sample A Test Method");
}
}
class SampleB:SampleA
{
public void Show()
{
Console.WriteLine("Sample B Test Method");
}
}
class Program
{
static void Main(string[] args)
{
SampleA a = new SampleA();
SampleB b = new SampleB();
a.Show();
b.Show();
a = new SampleB();
a.Show();
Console.ReadLine();
}
}
}
Output:
Sample A Test Method
Sample B Test Method
Sample A Test Method
So my question isn't the new keyword used to instantiated an object? and its used to allocate memory for new created objects? Then how can method hiding be done using it? And is above example correct?
new is used for 3 different things. You could say there are 3 different keywords with the same name.
It's an operator, used to invoke constructors. Example: new object();
It's a modifier, used to hide an inherited member from a base class member. Example:
class Base {
public void MyMethod() {
//Do stuff
}
}
class Derived : Base {
public new void MyMethod() {
//Do other stuff
}
}
It's a generic type constraint, used to indicate that a generic type parameter has a parameterless constructor. Example:
class MyGenericClass<T> : where T : new() { ... }
Source: new
Isn't the new keyword used to instantiated an object?
Yes it is. Among other things.
then how can method hiding done using it?
The new keyword in the context of method and property definitions has another meaning than the new keyword used to instantiate objects. The new keyword in that context tells that there is a new start of the inheritance tree of that particular method or property. That's all.
Then how can method hiding be done using it? And is above example
correct?
Programming language syntax, grammar and semantics are just an arbitrary set of conventions and specifications. That is, C# can invent one, two or dozen of usages of a given keyword like new.
When new is used during a class member declaration, it means that you're re-using an identifier:
public class A
{
public string Text { get; set; }
}
public class B : A
{
new public int Text { get; set; }
}
As you can check in above code sample, B also implements a Text property, but since derives from A which has also defined a Text property, there's a naming collision.
The so-called new keyword can be used to re-use Text identifier and being able to implement another property Text which may behave absolutely different than the one implemented in the base class. See that Text on B is of type int!
The most important point here is that re-using identifiers isn't the same as using polymorphism, where a class method or property override must match base class' member signature:
public class A
{
public virtual string Text { get; set; }
}
public class B : A
{
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
}
Also, re-used identifiers are dangerous:
public class A
{
public string Text { get; set; }
}
public class B : A
{
new public int Text { get; set; }
}
B b = new B();
b.Text = 4;
// Upcast B to A
A a = b;
a.Text = "Bye bye";
Console.WriteLine(a.Text); // Output: Bye bye
Console.WriteLine(b.Text); // Output: 4
See the output of Text. Since re-using identifiers isn't polymorphism, and in above case both are completely different properties, there's an A.Text and B.Text that can be set separately.
To hide an inherited member, declare it in the derived class by using the same member name, and modify it with the new keyword. For example:
public class BaseC
{
public static int x = 55;
public static int y = 22;
}
public class DerivedC : BaseC
{
// Hide field 'x'.
new public static int x = 100;
static void Main()
{
// Display the new value of x:
Console.WriteLine(x);
// Display the hidden value of x:
Console.WriteLine(BaseC.x);
// Display the unhidden member y:
Console.WriteLine(y);
}
}
/*
Output:
100
55
22
*/
You can read more in here
Consider the following very basic C# code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
for (int i = 1; i <= 100; i++)
{
int num = random.Next(1000);
string it_type;
if (num == 666)
{
System.Console.Write("Antichrist/satanistic trips get. Enjoy! ");
JonSkeet technician = new JonSkeet(); // Needs more Super::$tatic
technician.setup();
it_type = technician.getITType();
}
else
{
Whisperity technician = new Whisperity();
technician.setup();
it_type = technician.getITType();
}
System.Console.WriteLine(it_type + "... Prepare for next iteration.");
}
System.Console.ReadLine();
}
}
abstract public class ITTechnician
{
protected string itt_type = "Noname person.";
protected bool isJonSkeet = false;
public string getITType()
{
return this.itt_type;
}
abstract public void setup();
}
public class JonSkeet : ITTechnician
{
public override void setup()
{
this.itt_type = "Jon Skeet";
this.isJonSkeet = true;
}
}
public class Whisperity : ITTechnician
{
public override void setup()
{
this.itt_type = "Whisperity";
this.isJonSkeet = false;
}
}
}
How would I be able to set up a constructor in a way that the abstract class (abstract public void?) would require it and that I don't have to call technician.setup(); because the constructor takes care of setting the two internal variables. If I call the class functions the same name as the class itself, I get the following error:
Error 1 'Whisperity': member names cannot be the same as their enclosing
Also, my other question would be about optimization. Is there a way to define technician outside the if construct so something like the following could be executed: (This would omit having the classType technician = new classType(); lines twice, or is it unbypassable in C#?)
string it_type;
// Register 'technician' as a variable here.
if (num = 666)
{
technician = new JonSkeet();
}
else
{
technician = new Whisperity();
}
it_type = technician.getITType();
System.Console.WriteLine(it_type + "...");
Answer to your Question
You can provide a constructor with parameters in the abstract class.
abstract public class ITTechnician
{
public ITTechnician(string itt_type, bool isJonSkeet)
{
this.itt_type = itt_type;
this.isJonSkeet = isJonSkeet;
}
}
To construct a JonSkeet (if only it were so easy!)
JonSkeet jon = new JonSkeet("Jon Skeet", true);
Advice on Class Design
On a side note, I know this is a sample question, but you are not using object orientation well if a base class holds information that would differentiate classes that inherit from it.
Specifically this design would lead you to do things like
ITTechnician itt = GetSomeInstance();
if (itt.IsJonSkeet)
{
BehaviorA();
else
{
BehaviorB();
}
It is far cleaner to do something like
abstract public class ITTechnician
{
public abstract void Behavior();
// ...
}
public class JonSkeet
{
public override Behavior()
{
// Do awesome things
}
}
which allows the above code to be written as
ITTechnician itt = GetSomeInstance();
itt.Behavior();
How would I be able to set up a constructor in a way that the abstract
class would require it and that I don't have to call
technician.setup()
You don't need construct your logic to force the behavior of abstract class, but vice versa. Abstract class defines a stuf that has to be followed by the child.
If you create a simple parametless ctor in abstract class, which initializes the variables you need, whenever the child object will be constructed, the default ctor of abstract will be called before, so intialization will be executed.
To be more clear:
public class Child : Base
{
public Child(int x){
"Child".Dump();
}
}
public abstract class Base
{
public Base() {
//INIT VARIABLES HERE
"Base".Dump();
}
}
using these constructs like
vaar ch = new Child(); produces the result
"Base"
"Child"
If this is not what you're asking for, please clarify.
To discover a type at runtime, use GetType(). There's no need to create your own type string field.
The only thing that varies other than the intrinsic type in your class structure is IsJonSkeet. We can use a .NET property to implement this, which is a more modern and expressive way when compared to traditional private/protected fields with a Getter and maybe a Setter.
abstract public class ITTechnician
{
public bool IsJonSkeet { get; protected set; }
protected ITTechnician()
{
this.IsJonSkeet = false;
}
}
public class JonSkeet : ITTechnician
{
public JonSkeet()
{
this.IsJonSkeet = true;
}
}
public class Whisperity : ITTechnician
{
}
Now that your itt_type string field has been removed, Whisperity is the same as the base class, so there's no need for a constructor to do any initialisation - it will pick up the IsJonSkeet value of its parent automatically.
+1 for Eric J's class design tips, too. You should use the design of your hierarchy to encapsulate what varies and this makes your calling code much more transparent and the codebase easier to expand on in the future.
Since we know that constructor is not inherited in the child class as i asked in the my previous question Click here to view question
I had write the code
namespace TestConscoleApplication
{
abstract public class A
{
public int c;
public int d;
private A(int a, int b)
{
c = a;
d = b;
}
public virtual void Display1()
{
Console.WriteLine("{0}{1}", c, d);
}
}
internal class B : A
{
protected string Msg;
public B(string Err)
{
Msg = Err;
}
public void Display()
{
Console.WriteLine(Msg);
}
}
class Program
{
static void Main(string[] args)
{
B ObjB = new B("Hello");
Console.ReadLine();
}
}
}
when i compile the code its showing an error
Error TestConscoleApplication.A.A(int, int) is inaccessible due to its protection level.
Then why it is showing an error.
By making the only constructor of A private, you've prevented derived classes from being able to be constructed outside A.
Derived class constructor always call the base constructor (one of). Making it private you prohibit access to it from outside. In other words you make it impossible to make an instance of A outside A.
Since you made a constructor, the compiler won't generate a default public one for this class for you.
If you want to provide access to it from the class descendant but not from outside, you should make it protected.
You need to have a constructor for A accessible to B, and use it. Also, the default base constructor is base() (i.e. the parameterless constructor), which doesn't exist on A. Here's one way you can resolve this (nonessential bits removed):
abstract public class A
{
protected A(int a, int b)
{
}
}
internal class B : A
{
public B(int a, int b, string Err)
: base(a, b)
{
}
}
constructors shouldn't be private otherwise you will not be able to create an instance of that class and won't be able to inherit it too, but if you want to create a private constructor create a public one with it too.
For more info Go here