开发者

Order of derived classes in the console

my last problem is with inheritance in C#. I thought I understood this topic but somehow I am missing the point why the output is like that.

Here are my classes:

BaseClass:

public abstract class Vehicle
{
    public Vehicle()
    {
        Console.WriteLine("Honda Civic");
    }

    public abstract void Display();

}

Derived Class 1:

public class Vehicle4Wheels : Vehicle
{
    public override void Display()
    {
        Console.WriteLine("Derived111 class Constructor.");
    }
}

Derived Class 2:

public class SportCar : Vehicle4Wheels
{
    public new void Display()
    {
        Console.WriteLine("Derived222 class Constructor.");
        base.Display();
    }
}

This is the hierarchy: Base Class -> Derived Class 1 -> Derived Class 2

This is the output I am getting:

Honda Civic
Derived222 class Constructor.
Derived111 class Constructor.

This is the output I am trying to achieve:

Honda Civic
Derived111 class Constructor.
Derived222 class Constructor.

I have read several articles where it was stated that base class is printed first and the other derived classes are printed based on their spot in the hierarchy.

So why is the last derived class printed before the first derived class? What am I missing (except C# programming skills)?

Thank for the answers.

EDIT:

I am sorry it took me a while to get back to this thread. To be more precise, I will post the task of the homework I am trying to achieve:

Work 2:
An abstract class is not a complete class, it misses some parts, and you cannot create    
objects from it. The programmer who writes the derived classes must fill in the missing   
parts. Consider an abstract class Vehicle. Derive two hierarchies from this class as it 
is shown below: Now, write 4 classes, see the yellow rectangle. Start from the abstract 
base class Vehicle -> Vehicle with 4 wheels -> Sport Cars and stop at the derived class Rally, which is the most specific 
class. The class Vehicle contains a field which holds the vehicle name and an abstract 
method void Display().

Implement this function in the derived classes, so that the function returns 
information about the vehicle, e.g. the motor power and other necessary properties. The 
last derived class has private fields to hold the motor power, the car weight, the car 
acceleration, the highest speed and a function that computes the specific power (power 
/ weight). The function Display returns a text string with all this information. Test 
your work in a Console application that uses objects of the type of the classes Sport 
car and Rally.

Class Vehicle:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace A_work_2
{
public abstract class Vehicle
{
    public string vehicleName;
    public abstract void Display();

}
}

Class Vehicle4Wheels:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace A_work_2
{
public class Vehicle4Wheels : Vehicle
{
    public override void Display() 
    {
        Console.WriteLine("Car1");
    }
}
}

Class SportCar:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace A_work_2
{
public class SportCar : Vehicle4Wheels {
    public override void Display()
    {
        Console.WriteLine("Derived222 class Constructor.");
    }
}
}

Class Rally:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace A_work_2
{
public class Rally : SportCar
{
    private double motorPower = 408;
    private double carWeight = 2380;
    private double carAcceleration = 4.7;
    private double highestSpeed = 250;

    public double SpecificPower()
    {
        double specificPower = motorPower / carWeight;
        return specificPower;
    }

    public override void Display()
    {

       Console.WriteLine("The acceleration is: {0}.\nThe highest speed is {1} km/h.", carAcceleration, highestSpeed);
       Console.WriteLine("Specific power is {0}", SpecificPower());


    }
}
}

I am not sure how to achieve the goal of the task with abstract methods. Thank you开发者_JS百科 for answers, V.


You are mixing the concept of a constructor with the concept of a virtual method. Constructors are indeed called in order from base to derived, but you have created non-constructor virtual methods.

This will give the output you wanted:

// In Vehicle4Wheels
public Vehicle4Wheels()
{
    Console.WriteLine("Vehicle4Wheels constructor");
}

// In SportCar
public SportCar()
{
    Console.WriteLine("SportCar constructor");
}

(Also, edit the string you are printing in the Display() methods, since they are misleading - Display() is not a constructor.)

As for virtual methods (note that abstract methods automatically become virtual), the "most derived" class' method is the one that is called, and only that method is called - unless the method invokes base.MethodName().


This is the output I am getting: Honda Civic Derived222 class Constructor. Derived111 class Constructor.

This is the output I am trying to achieve: Honda Civic Derived111 class Constructor. Derived222 class Constructor.

Ok, just swap the calls:

public new void Display()
    {
        base.Display();
        Console.WriteLine("Derived222 class Constructor.");
    }


You first Get Honda Civic because it is output during the creation of the base class. the constructors of the base class is the first thing that is perform during the constructor of the inherited class.

Then you Get Derived222 because it is output first in your display method.


Change your code that way :

public abstract class Vehicle {
    public Vehicle() { Console.WriteLine("Honda Civic"); } 
}

public class Vehicle4Wheels : Vehicle {
    public Vehicle4Wheels() { Console.WriteLine("Derived111 class Constructor."); }
}

public class SportCar : Vehicle4Wheels {
    public SportCar() { Console.WriteLine("Derived222 class Constructor."); 
}

you don't need to override the Display() method in what you(re trying to achieve.

And beware of the use of the new keyword when declaring a method ;-)


You didn't show the code you are using to test your classes, but I think it is something like this:

SportCar car = new SportCar();
car.Display();

The first thing that is not so clear is why you are writing on the console in the constructor of the abstract class, but in a method of the derived ones. This means that, apart from the order of the messages, Honda Civic is written as soon as you create an instance of each one of your classe, while the other messages are written only when you call the Display method (even if you write Constructor in the method).

@Seb gave you the right way to go if you want to do specific things in the constructors of a hierarchy of classes, but if you really wanted to write different versions of the method Display, you must be careful to the use of override and new. If a method is virtual or abstract, you should always use override, and leave the use of new to the cases in which you want to hide the method defined in the base classes. You can find an example (using cars like you :-)) here: [http://msdn.microsoft.com/en-us/library/ms173153(v=vs.80).aspx].

If you use override, the method being executed is determined at run time and depends on the type of the object. If you use new the method being executed is determined at compile time and depends on the type of the variable you assign your object to. For instance, if you execute this piece of code with your classes:

        Console.WriteLine("This is the constructor");
        SportCar car = new SportCar();
        Console.WriteLine("This is the first call to display");
        car.Display();
        Vehicle4Wheels car2 = car;
        Console.WriteLine("This is the second call to display");
        car2.Display();

The result is:

This is the constructor
Honda Civic
This is the first call to display
Derived222 class Constructor.
Derived111 class Constructor.
This is the second call to display
Derived111 class Constructor.

Replacing the new with an override you obtain what you are probably expecting:

This is the constructor
Honda Civic
This is the first call to display
Derived222 class Constructor.
Derived111 class Constructor.
This is the second call to display
Derived222 class Constructor.
Derived111 class Constructor.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜