Reputation: 1415
I tried the below code in my c# program. This is just for learning the OOPs Concepts.
class a
{
public void testa()
{
}
}
class b:a
{
public void testb()
{
}
}
a a1 = new b();
b b1 = new a();
I have the following queries regarding the code mentioned above.
a a1=new b()
;a1.testb()
is not accessible even though constructor of b
is assigned to a1
?a a1=new a()
and a a1=new b()
?Upvotes: 4
Views: 7826
Reputation: 24666
Probably inheritance and polymorphism concepts are not so clear for you yet. This article may help you.
If class b
inherits from a
, you can imagine it as a "specialization" of a
.
So you can easily understand that b
can be used/seen as an a
instance, but the reverse is not true!
Why Im getting error in 2nd line?
because b b1 = new a();
is not a valid assignment. As explained, you can assign inherited class instance to base class variable, but not the contrary!
what is meant by a a1=new b();
this assignment is correct because you can surely use a more specific class instance as a base class instance.
why a1.testb() is not accessible even though constructor of b is assigned to a1?
when you inherit from a class, all the public
and protected
methods of this class are inherited and you can access or override that in the new class. but testb()
is not an inherited method. is a new method defined inside class b
so you can use it only if you do this assignment: b b1=new b();
Upvotes: 3
Reputation: 29243
Think of your classes as a contract, guaranteeing the existence of certain operations.
Class a
defines one operation, class b
inherits all operations from a
and defines another one of its own.
The first line:
a a1 = new b();
Declares a variable named a1
of type a
, meaning whatever value you give this variable should have all the operations type a
requires. new b()
creates a new instance of class b
, which is assigned to variable a1
. Since class b
inherits all operations from type a
, a value of type b
can be assigned to a variable of type a
.
On the second line:
b b = new a();
Similarly, you define a variable which should have all the operations defined by type b
. But since you put in a value of type a
which doesn't define the testb
operation type b
requires, the compiler doesn't accept this.
As for your third question, the compiler only knows the type of your variable (a
), not which value you actually assigned to it. You basically told the compiler "I guarantee this value will define the testa
operation. Now let it do operation testb
!" The compiler doesn't know the actual value of the variable, so as far as it's concerned, that's not possible.
As for the difference between a a1=new a()
and a a1=new b()
:
In both cases, a variable of type a
is created. In the first expression, the value assigned to this variable is a newly created instance of type a
, while in the second, the value is a newly created instance of type b
. Since type 'b' is basically an expanded version of type a
, the compiler know that everything you could ask of an instance of type a
can also be satisfied by an instance of type b
, so it just treats the value as if it is of type a
.
Upvotes: 1
Reputation: 27585
I change your class and method names to real world equivalents to better understanding. I name a
as Animal
, testa
as Eat
, b
as Human
, and testb
as Talk
. So we have:
class Animal {
public void Eat() { }
}
class Human : Animal {
public void Talk() { }
}
Animal a1 = new Human();
Human b1 = new Animal();
OK, return to your questions.
1) You get error on second line, because every animal is NOT a human. Is it?
2) a1=new b()
according to our new naming conventions, turns to a1 = new Human
which means Animal a1 = new Human
. So, that's correct, because human is a kind of animal.
3) a1.testb()
according to our new naming conventions, turns to a1.Talk()
. Well, a1
is an animal (Animal a1
), and we can not expect an animal to talk.
MORE:
Think a class
is a group of attributes and behaviors. For example, we have a group named Animal
that defines an Eat
behavior. And another group named Human
that extends Animal
group and also it has its own behavior named Talk
. As we know, Human
has its super-group behaviors too -e.g. Eat
in this example-.
When we have an instance of group Animal
, we can expect it to eat. But we can not ask it to talk. It's not possible. In the other hand, every item that we choose from group Human
, is actually an Animal
. So we can ask him to eat.
When we have a Human
instance, we can ask him to behave as a Human
and as an Animal
too. I mean, we can ask him to Talk
and we can ask him to Eat
too. Every Human
can be located in human group, and in animal group.
1) When we say Human b1 = new Animal();
it says exactly: pick up an item from Animal
group - right part - and put it in Human
group - left part - which is not possible. Because there are a lot of animals which are not human.
2) When we say Animal a1 = new Human
: pick up an item from Human
group - right part - and put it in Animal
group - left part - which is easily possible.
3) When we say a1.Talk()
, we expect an Animal
to talk. I mean we expect an Animal
to act a Human
behavior which is not possible.
Upvotes: 4
Reputation: 141575
1) if you mean this line:
b b = new a();
it is because every b
is a
but not every a
is b
2-3) what is meant by a a1=new b();
why a1.testb()
is not accessible even though constructor of b
is assigned to a1
?
it means that you create object of b
class but get reference to it as a
(you can treat it trough this reference without casting only as a
even it is b
)
Upvotes: 4
Reputation: 13620
1) Every b
is an a
but the converse is not true.
2) is an example of Polymorphism Polymorphism - Define In Just Two Sentences
3) a1.testb()
is not accessible because you are treating it as an instance of a
which has no definition for testb()
Upvotes: 0
Reputation: 4683
If you defined a a1 = new b() , to use methods declared in b you can cast a1 as b
a a1 = new b();
((b)a1).testb();
Upvotes: 1