Порядок производных классов в консоли - PullRequest
2 голосов
/ 03 октября 2011

моя последняя проблема с наследованием в C #. Я думал, что понял эту тему, но почему-то мне не хватает того, почему вывод такой.

Вот мои занятия:

BaseClass:

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

    public abstract void Display();

}

Производный класс 1:

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

Производный класс 2:

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

Это иерархия: Базовый класс -> Производный класс 1 -> Производный класс 2

Это вывод, который я получаю:

Honda Civic
Derived222 class Constructor.
Derived111 class Constructor.

Вот вывод, который я пытаюсь достичь:

Honda Civic
Derived111 class Constructor.
Derived222 class Constructor.

Я прочитал несколько статей, в которых было указано, что базовый класс печатается первым, а другие производные классы печатаются в зависимости от их места в иерархии.

Так почему последний производный класс печатается перед первым производным классом? Чего мне не хватает (кроме навыков программирования на C #)?

Спасибо за ответы.

EDIT:

Извините, мне потребовалось некоторое время, чтобы вернуться к этой теме. Чтобы быть более точным, я опубликую задачу домашней работы, которую я пытаюсь выполнить:

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.

Автомобиль класса:

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

}
}

Класс 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");
    }
}
}

Класс 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.");
    }
}
}

Классное ралли:

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


    }
}
}

Я не уверен, как достичь цели задачи абстрактными методами. Спасибо за ответы, V.

Ответы [ 5 ]

5 голосов
/ 03 октября 2011

Вы смешиваете концепцию конструктора с концепцией виртуального метода . Конструкторы действительно вызываются в порядке от базового к производному, но вы создали неконструктивные виртуальные методы.

Это даст желаемый результат:

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

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

(Кроме того, отредактируйте строку, которую вы печатаете, в методах Display(), поскольку они вводят в заблуждение - Display() это , а не конструктор.)

Что касается виртуальных методов (обратите внимание, что abstract методы автоматически становятся виртуальными), то вызывается метод «самого производного» класса, и вызывается только этот метод - если только метод не вызывает base.MethodName().

1 голос
/ 03 октября 2011

Это вывод, который я получаю: Конструктор класса Honda Civic Derived222.Конструктор класса Derived111.

Вот вывод, который я пытаюсь достичь: Конструктор класса Honda Civic Derived111.Конструктор класса Derived222.

Хорошо, просто поменяйте местами звонки:

public new void Display()
    {
        base.Display();
        Console.WriteLine("Derived222 class Constructor.");
    }
0 голосов
/ 03 октября 2011

Вы не показывали код, который используете для тестирования своих классов, но я думаю, что это что-то вроде этого:

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

Первое, что не так понятно, это то, почему вы пишете наконсоль в конструкторе абстрактного класса, но в методе производных.Это означает, что, помимо порядка сообщений, Honda Civic записывается, как только вы создаете экземпляр каждого вашего класса, а другие сообщения пишутся только при вызове метода Display (даже если вы пишете Constructor вметод).

@ Себ дал вам правильный путь, если вы хотите делать определенные вещи в конструкторах иерархии классов, но если вы действительно хотите написать разные версии метода Display, вы должны быть осторожны сиспользование переопределения и нового.Если метод является виртуальным или абстрактным, вы всегда должны использовать переопределение и оставлять использование new для случаев, когда вы хотите скрыть метод, определенный в базовых классах.Вы можете найти пример (используя такие автомобили, как вы :-)) здесь: [http://msdn.microsoft.com/en-us/library/ms173153(v=vs.80).aspx].

Если вы используете переопределение, выполняемый метод определяется во время выполнения и зависит от типа объекта.Если вы используете new, то выполняемый метод определяется во время компиляции и зависит от типа переменной, которой вы назначаете свой объект.Например, если вы выполняете этот фрагмент кода с вашими классами:

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

Результат:

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.

Заменив новый на переопределение, вы получите то, что вы, вероятно, ожидаете:

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 голосов
/ 03 октября 2011

Измените свой код таким образом:

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."); 
}

вам не нужно переопределять метод Display() в том, что вы (пытаетесь достичь.

и остерегайтесь использованияключевого слова new при объявлении метода; -)

0 голосов
/ 03 октября 2011

Сначала вы получаете Honda Civic, потому что он выводится при создании базового класса.конструкторы базового класса - это первое, что выполняется во время конструктора унаследованного класса.

Затем вы получаете Derived222, потому что он сначала выводится в вашем методе отображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...