C# 在C语言中解决继承问题#

C# 在C语言中解决继承问题#,c#,inheritance,C#,Inheritance,我在理解如何实现继承方面遇到了一些困难 我的模型纯粹是为了演示,但现在我们开始: 我有一个父类Bus。它有两个子系统DieselBus和ElectricBus。这些是抽象类 我还有另外两个班Coach和CityBus。我如何设置从DieselBus或ElectricBus继承而不必定义单独的Coach和CityBus类,如CoachDieselBus、CoachElectricBus、CityBusDieselBus?这是否可行/可能 到目前为止,我没有缺少一些骨架的例子,希望在这一点上得到建议

我在理解如何实现继承方面遇到了一些困难

我的模型纯粹是为了演示,但现在我们开始:

我有一个父类
Bus
。它有两个子系统
DieselBus
ElectricBus
。这些是抽象类

我还有另外两个班
Coach
CityBus
。我如何设置从
DieselBus
ElectricBus
继承而不必定义单独的
Coach
CityBus
类,如
CoachDieselBus
CoachElectricBus
CityBusDieselBus
?这是否可行/可能

到目前为止,我没有缺少一些骨架的例子,希望在这一点上得到建议

我要找的是:

与此相反:

谢谢

编辑(2013-07-03):

首先,一些代码:

巴士公司

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

namespace InheritanceTest {
    abstract class Bus {
        public Bus () {

        }

        public abstract Engine EngineType {
            get;
            set;
        }

        private int id;
        public int ID {
            get {
                return id;
            }
            set {
                id = value;
            }
        }

        private int seats;
        public int Seats {
            get {
                return seats;
            }
            set {
                seats = value;
            }
        }

        private float length;
        public float Length {
            get {
                return length;
            }
            set {
                length = value;
            }
        }

        private String colour;
        public String Colour {
            get {
                return colour;
            }
            set {
                colour = value;
            }
        }
    }
}
Coach.cs

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

namespace InheritanceTest {
    class Coach : Bus {
        public Coach (int id, int seats, float length, String colour, String company, Engine engine) {
            this.ID = id;
            this.Seats = seats;
            this.Length = length;
            this.Colour = colour;
            this.EngineType = engine;
            this.company = company;
        }

        public override Engine EngineType {
            get;
            set;
        }

        private String company;
        public String Company {
            get {
                return company;
            }
            set {
                company = value;
            }
        }

        public override string ToString () {
            return (this.ID + "\t" + this.Seats + "\t" + this.Length + "\t" + this.Colour + "\t" + this.Company + "\t" + this.EngineType.ToString ());
        }
    }
}
Engine.cs

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

namespace InheritanceTest {
    abstract class Engine {
        public Engine () {

        }

        private float power;
        public float Power {
            get {
                return power;
            }
            set {
                power = value;
            }
        }

        private float torque;
        public float Torque {
            get {
                return torque;
            }
            set {
                torque = value;
            }
        }

        private int redline;
        public int Redline {
            get {
                return redline;
            }
            set {
                redline = value;
            }
        }
    }
}
柴油发动机

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

namespace InheritanceTest {
    class DieselEngine : Engine {
        public DieselEngine (float power, float torque, int redline, float displacement, float fuelEconomy) {
            this.Power = power;
            this.Torque = torque;
            this.Redline = redline;
            this.displacement = displacement;
            this.fuelEconomy = fuelEconomy;
        }

        private float displacement;
        public float Displacement {
            get {
                return displacement;
            }
            set {
                displacement = value;
            }
        }

        private float fuelEconomy;
        public float FuelEconomy {
            get {
                return fuelEconomy;
            }
            set {
                fuelEconomy = value;
            }
        }

        public override string ToString () {
            return "Diesel Engine";
        }
    }
}
我的程序执行有问题:

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

namespace InheritanceTest {
    class Program {
        static void Main (string[] args) {
            String line;
            var diesel = new DieselEngine (200F, 550F, 3500, 7.5F, 10F);
            var electric = new ElectricEngine (85F, 1000F, 19000, 24F, 65000F);
            var city = new CityBus (124, 75, 18.5F, "Red", "Brisbane", electric);
            var coach = new Coach (777, 120, 22.5F, "Blue", "GreyHound", diesel);
            line = new String ('-', city.ToString ().Length * 2);

            System.Console.WriteLine ("City Buses\n\nID\tSeats\tLength\tColour\tCity\t\tEngine Type");
            System.Console.WriteLine (line);
            System.Console.WriteLine (city.ToString ());

            System.Console.WriteLine ("\n\nCoach Buses\n\nID\tSeats\tLength\tColour\tCompany\t\tEngine Type");
            System.Console.WriteLine (line);
            System.Console.WriteLine (coach.ToString ());

            System.Console.ReadKey (true);
        }
    }
}
无论我如何尝试,我都无法访问从相关总线继承引擎的任何类的任何属性。例如,我看不到我给
Coach
“Coach”的
DieselEngine
位移量

在C#中,您只能从一个类继承,因此只能从第二个图中显示的类继承

您可以使用接口,因为一个类可以实现多个接口,但接口实际上应该更多地用于定义行为,而不是类的属性/质量,柴油机/电动汽车和城市/客车似乎更像公交车的属性

我还有两个班的长途客车和城巴。我如何设置从DieselBus或ElectricBus继承而不必定义单独的Coach和CityBus类,如CoachDieselBus、CoachElectricBus、CityBusDieselBus和CitybuseElectricBus?这是否可行/可能

不,那不可行。继承关系必须是固定的,因此
Coach
必须始终具有相同的父类

您的问题的适当解决方案是使用组合而不是继承:
Coach
CityBus
都继承自
Bus
<代码>总线
具有一个
发动机
属性,该属性可以设置为
柴油发动机
电动发动机


(对不起,这张简陋的图表,我现在只有MS Paint可用。)

像往常一样,当这个问题出现时,混乱从一个不可行的类树开始。我个人认为这些都不是继承问题

公共汽车有一个发动机,它是柴油发动机和电动发动机的基本类

公共汽车的用法可能是City和Coach的基类

这里使用继承是一种经典的反模式。一个典型的初学者错误——所以不要为此感到难过。结果大多是过于复杂的继承树


您可以选择使用接口(IDieLengine、IElectricEngine),但我可能会选择composition。

以下是一个示例,说明如何做您想做的事情

public abstract class Engine
{
    public abstract string Name { get; set; }
}

public class DieselEngine:Engine
{
    public override string Name { get; set; }

    public string DieselEngineProperty { get; set; }
}

public class ElectricEngine : Engine
{
    public override string Name { get; set; }

    public string ElectricEngineProperty { get; set; }
}

public class HybridEngine : Engine
{
    public override string Name { get; set; }

    public string HybridEngineProperty { get; set; }
    public List<Engine> EngineList { get; set; }
}



public abstract class Bus
{
    public abstract string Name { get; set; }
    public abstract string Lengh { get; set; }
    public abstract Engine BusEngine { get; set; }
}

public class CoachBus: Bus
{
    public override string Name { get; set; }

    public string CoachBusProperty { get; set; }
}

public class CityBus:Bus
{

    public override string Name { get; set; }
    public override string Lengh { get; set; }
    public override Engine BusEngine { get; set; }

    public string CityBusProperty { get; set; }
}

你考虑过战略设计模式吗?@VinayPandey我不太熟悉concept@capncoolio要访问属性,您只需请求对象获取引擎,然后请求引擎获取属性示例:
coach.EngineType.Power
@WiiMaxx谢谢您的回复,这正是我遇到的问题;它可以让我看到发动机的性能,但无论是柴油发动机还是电动发动机,都不能看到,不管我给了哪一辆车@卡彭科利奥:哦,我误解了你。要访问此属性,您需要将
EngineType
强制转换为您
键入的引擎
需要示例:
var dieselE=coach.EngineType.Power as dieseEngine;//如果播放不成功,dieselE将为空
谢谢您的建议!我应该更清楚这一点,但到目前为止,作为一名学生,我只需要处理一次继承问题…@capncoolio:你真的需要访问详细的属性吗?理想情况下,
Engine
将提供引擎所需的所有方法和属性,
DieselEngine
ElectricEngine
将以不同的方式实现它们。如果您确实需要对引擎类型的详细访问,您可以将总线设置为通用,即
Bus
,但是,如果不指定特定类型的引擎,那么使用通用总线实例将更加困难。因此,我应该保存
总线
类中的所有属性,然后在
DieselEngine
ElectricEngine
中重写它们?然后,我如何确保您无法从
电动发动机中查看
柴油发动机
属性,反之亦然?噢,非常感谢您的帮助,我非常感谢!
        var myDieselEngine = new DieselEngine();
        myDieselEngine.Name = "TöffTöff";

        var myElectricEngine = new ElectricEngine();
        myDieselEngine.Name = "SumSum";

        var myHybridEngine = new HybridEngine();
        myDieselEngine.Name = "SumTöff";

        var myDieselCityBus = new CityBus();
        myDieselCityBus.Name = "Shorty1";
        myDieselCityBus.Lengh = "5 m";
        myDieselCityBus.BusEngine = myDieselEngine;

        var myElectricCityBus = new CityBus();
        myElectricCityBus.Name = "Shorty2";
        myElectricCityBus.Lengh = "7 m";
        myElectricCityBus.BusEngine = myElectricEngine;

        var myHybridCoachBus = new CoachBus();
        myHybridCoachBus.Name = "Shorty2";
        myHybridCoachBus.Lengh = "15 m";
        myHybridCoachBus.BusEngine = myHybridEngine;