2014-03-06 147 views
2

我在理解如何實現繼承時遇到了一些麻煩。解決C#中的繼承問題

我的模型是純粹爲示範的緣故,但在這裏我們去:

我有一個父類Bus。它有兩個子女DieselBusElectricBus。這些是抽象類。

我還有兩類CoachCityBus。我如何將這些設置爲從DieselBusElectricBus繼承,而不必定義單獨的CoachCityBus類,如CoachDieselBus,CoachElectricBus,CityBusDieselBusCityBusElectricBus?這甚至可行/可能嗎?

到目前爲止,我還沒有一些簡單的例子來尋找關於這一點的建議。

我所尋找的是這樣的: Correct

與此相反: Incorrect

謝謝!

編輯(2013年7月3日):

首先,一些代碼:

Bus.cs

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; 
      } 
     } 
    } 
} 

DieselEngine.cs

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

無論我如何努力,我不能訪問任何的兩個類的屬性從相關的巴士繼承引擎。例如,我看不到DieselEngineDisplacement我給Coach「教練」。

+0

你有沒有考慮戰略設計模式? –

+0

@VinayPandey我不熟悉那個概念 –

+0

@capncoolio來訪問你只需要詢問對象獲取引擎的屬性,然後向引擎請求屬性示例:'coach.EngineType.Power' – WiiMaxx

回答

6

我還有兩堂課Coach和CityBus。我如何設置這些繼承自DieselBus或ElectricBus而不必定義像CoachDieselBus,CoachElectricBus,CityBusDieselBus和CityBusElectricBus這樣的單獨的Coach和CityBus類?這甚至可行/可能嗎?

不,那是行不通的。繼承關係必須是固定,所以Coach必須始終具有相同的父類。

有關問題的適當的解決方案是使用組成,而不是繼承CoachCityBus無論從Bus繼承。 Bus有一個Engine屬性,它可以設置爲DieselEngineElectricEngine

Diagram

(對不起,粗圖,我只有MS畫圖可用的現在。)

+0

感謝您的幫助,這使得它更清晰。 –

+0

對我的新編輯帖子有任何建議? –

+0

@capncoolio:你真的需要訪問詳細的屬性嗎?理想情況下,'Engine'將提供引擎所需的所有方法和屬性,而'DieselEngine'和'ElectricEngine'只是以不同的方式實現它們。 – Heinzi

1

在C#中,只能從一個類繼承,因此只有第二個圖中顯示的類是可能的。

您可以使用接口作爲一個類可以實現多個接口,但接口應該更多地用於定義行爲,而不是類和柴油/電力和城市/教練的屬性/質量看起來更像您公共汽車的屬性。

2

像往常一樣,當這個問題到來時,混亂與不可行的分類開始。我個人會說,他們都不是遺產問題。

公交車有一臺發動機,它是DieselEngine和ElectricEngine的基礎級別。

公交車有一個用途,它可能是城市和教練的基類。

這裏使用繼承是一個古典的反模式。一個典型的初學者錯誤 - 所以不要爲此感到不快。結果主要是方式太複雜的繼承樹。

您可能會選擇使用接口(IDieselEngine,IElectricEngine),但我可能會與組成去。

+0

感謝您的諮詢!我應該可能比這更清楚,但是到目前爲止,我只需要處理一次學生繼承問題...... –

1

下面是你怎麼可以做你想做

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; } 
} 

什麼的例子,這裏有一些公交車

 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; 
+0

感謝示例代碼,它有助於清除它很多! –