Why should I put a class2 reference in a class 1 object?

Ok, so I found this piece of code:

class1 a = new class1(); a.Test(); class1 b = new class2(); b.Test(); 

This has something to do with virtual and overriding, but now my question is: Why enter

 class1 b = new class2(); 

when you can just enter

 class2 b = new class2(); 

since both solutions have the same output

+4
source share
7 answers

A derived class that uses the "new" keyword for a method instead of "overriding" will behave differently depending on how it is executed.

Example:

 class Class1 { public virtual void DoSomething { Console.WriteLine("Class1.DoSomething"); } } class Class2 : Class1 { public new void DoSomething { Console.WriteLine("Class2.DoSomething"); } } class Class3 : Class1 { public override void DoSomething { Console.WriteLine("Class3.DoSomething"); } } 

Classes 2 and 3 come out of class 1, but class 2 uses the keyword "new" to "hide" the virtual member of class 1, while class 3 uses the keyword "override" to "override" the virtual member of class 1. Here's what happens when you use these classes as your own types:

 Class1 one = new Class1(); one.DoSomething(); // outputs "Class1.DoSomething" Class2 two = new Class2(); two.DoSomething(); // outputs "Class2.DoSomething" Class3 three = new Class3(); three.DoSomething(); // outputs "Class3.DoSomething" 

They all return the correct class name, as expected. But this is what happens when you use these classes as class 1:

 Class1 one = new Class1(); one.DoSomething(); // outputs "Class1.DoSomething" Class1 two = new Class2(); two.DoSomething(); // outputs "Class1.DoSomething" Class1 three = new Class3(); three.DoSomething(); // outputs "Class3.DoSomething" 

Since class 2 "hides" the method, it will output "Class2.DoSomething" when used as its own type, but it will output "Class1.DoSomething" when used as the base type. But since class 3 "overrides" the method, it outputs "Class3.DoSomething" whether it is used as its own type or as the base type, because it "redefines" the functionality of the base type.

(Another effect of this is that if Class2 or Class3 have an additional method, say DoSomethingElse , you cannot call Class1 two = new Class2(); two.DoSomethingElse() because Class1 does not have this method.)

I don't know about any real use cases for this, but it is, and this is the only way I can think that using Class1 class2 = new Class2() will offer any real use. If Class2 does not β€œhide” any members of Class1 , then there is no real benefit.

See: http://msdn.microsoft.com/en-us/library/ms173153.aspx

+1
source

class1 is obviously a superclass of class 2. Thus, you can, for example, have a list of class1 objects, all of which contain class1 or class2 objects. You can simply add a and b to this list without any problems.

 class Class1 { public virtual void test(){ //do something { } class Class2 : Class1 { public override void test(){ // do something else } } IList<Class1> list = new List<Class1>(); Class1 a = new Class1(); Class1 b = new Class2(); list.add(a); list.add(b); 

Then, trying to get an item from this list, you can simply do:

 list[0].test(); //calls test of Class1 list[1].test(); //calls test of Class2 

This concept is called polymorphism (poly = many, morph = shape).

+2
source

Suppose B1 and B2 are deduced from A Then you may not know until runtime whether you have B1 or B2 . In this case, you should statically generalize to A , which can accommodate both subtypes. If inheritance is used correctly, you don't care what the specific type of runtime is.

Example:

 A a = GetA(); A GetA() { if (Random()) return new B1(); else return new B2(); } 

Since it can be either B1 or B2 , you should use a common base class for variable type ( A ).

+1
source

This is a matter of abstraction and free communication. If the code depends only on the type "class1" and not on "class2" (which is a specific subclass of class 1), then the code is more general, and you can easily switch to another subtype of class1 without changing another code.

Example: let's say you have an abstract List class. It has two subclasses, ArrayList and LinkedList . They work more or less the same way (like a list of items), but are implemented differently, giving them different performance characteristics. When you write your code, you do not know which implementation is most suitable for your code. Therefore, you want to write your code in such a way that you are not dependent on the features of any of the specific subclasses.

If your code only takes care that the class is List , then you would only need to name the specific subclass once:

 List x = new LinkedList(); 

Elsewhere, you can think of it as a more general List class. This provides two things:

  • If you decide to use ArrayList insted from LinkedList , you only need to change the code in one place.
  • You do not accidentally depend on the specific implementation details of one of the specific subclasses, for example. by calling a method that exists on only one of them. By dropping the base class, the type checker ensures that you can call methods common to all subclasses. This again means that you can simplify the swap implementation.

For example, List will define some methods and properties, such as say Count and Item , which will then be supported by all subclasses. But specific subclasses can also define additional methods, for example say Resize for ArrayList and IsCircular for LinkedList , which makes sense only for a particular subclass.

By declaring a variable as a more general type, List , you guarantee that you will not depend on certain methods or properties related to the subclass, since the compiler will simply not let you use them.

+1
source

This is called Polymorphism . In short, it allows you to create several subclasses and treat them as a parent, this has some advantages, such as preventing code duplication.

0
source

I will add another answer to answer the question of why someone, in their right mind, would have typed it that way.

The only case where this can behave differently is if class2 and class1 have a method with the same name but do not use virtual inheritance. This can be done using the new keyword (or no keyword at all that will compile, but launches a well-deserved warning).

This is a bad style and is almost never useful. This is probably not what he wanted.

It might make sense to write it in such a way as to document the fact that only class1 members are class1 . He can say that the fact that he really is class2 at runtime does not matter. This is most likely due to virtual inheritance.

So this can be purely for documenting intent.

0
source

You can use this instatiating example in the "Factory" template. This is the first use I can think of.

-one
source

Source: https://habr.com/ru/post/1501184/


All Articles