简体   繁体   中英

C# creating an instance of a class and derived class

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.

  1. Why Im getting error in 2nd line?
  2. what is meant by a a1=new b() ;
  3. why a1.testb() is not accessible even though constructor of b is assigned to a1 ?
  4. what is the difference between a a1=new a() and a a1=new b() ?

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 )

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 -eg 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.

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();

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();

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 .

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM