0

しばらくの間、C# (および他のいくつかの言語) でプログラミングを行ってきましたが、最近、オブジェクト指向プログラミングの感覚をつかむために、カスタム クラスの記述を開始する必要があると判断しました。そのために、継承に取り組むために、Vehicle の基本クラスといくつかの派生クラスから始めました。

ここで私がやろうとしているのは、Vehicle の基本呼び出しにいくつかのデフォルト値とロジックを設定し、派生クラスに違いを決定するいくつかの情報を実装させることです。たとえば、基本クラスで _wheelsNumber、_motorType、および _horsePower 変数とロジックを設定している間に、各クラス (Car、Truck、Semi、Moped など) で _wheelsNumber を設定し、ロジックの流れをトリガーして計算します。残りのプロパティを削除します。

ただし、これらの目的を達成するために適切な方法でクラスを作成したかどうかはわかりません。コンストラクターと get/set アクセサーを使用してリモートで正しいことを行っているかどうかについては明確ではありません (ユーザーに車の車輪の数などを選択させたくないため、私はしていません)宣言された set アクセサー)。私が気づいたと思うことの 1 つは、ユーザーがモーターの種類の前と馬力の前に車輪の数をプログラムに問い合わせる必要があることです。これは、コンストラクター内で計算されていないためだと思いますが、よくわかりません。

誰でも明確に理解していただければ幸いです。

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

namespace VehicleClasses
{
    abstract public class Vehicle
    {
        protected const int smallMotor = 1;
        protected const int mediumMotor = 3;
        protected const int largeMotor = 5;
        protected const int largerMotor = 7;
        protected const int hugeMotor = 9;
        protected const int wrongMotor = 9001;

        public Vehicle()
        {
            _horsePower = (_motorType * _motorType) * 8;
        }

        protected int _wheelsNumber;
        public int wheelsNumber
        {
            get
            {
                return _wheelsNumber;
            }
        }

        protected int _motorType;
        public int motorType
        {
            get
            {
                if (_wheelsNumber < 4)
            {
                _motorType = smallMotor;
            }

            else if (_wheelsNumber >= 4 && wheelsNumber <= 6)
            {
                _motorType = mediumMotor;
            }

            else if (_wheelsNumber > 6 && wheelsNumber < 10)
            {
                _motorType = largeMotor;
            }

            else if (_wheelsNumber >= 10 && wheelsNumber < 18)
            {
                _motorType = largerMotor;
            }

            else if (_wheelsNumber >= 18)
            {
                _motorType = hugeMotor;
            }

            else
            {
                _motorType = wrongMotor;
            }                
                return _motorType;
            }
        }

        protected int _horsePower;
        public int horsePower
        {
            get
            {
                return _horsePower;
            }
        }
    }
}
4

1 に答える 1

0

これは継承の一般的な誤用です。サブクラスは、状態の値を変更するだけでなく、動作を拡張する必要があります。

あなたの例では、自由変数は車輪の数だけです。他のすべてはそれに基づいて派生した特性です。vehicle のコンストラクタを引数として車輪の数を受け取るように変更し、(必要に応じて) 正しい数の車輪を持つ車両を作成する "CreateMotorcycle()" などの public static メソッドをクラスに追加できます。

代替の推奨エクササイズ

前述したように、継承は動作を拡張する場合に役立ちます。たとえば、「従業員」基本クラスがあるとします。簡単にするために、各従業員には 1 人の後輩と 1 人の先輩がいるとします。

従業員が休みたいときはいつでも上司に頼まなければなりませんが、すべての従業員が承認できるわけではありません。リクエストは、派生インスタンスである「マネージャー」に到達するまでチェーンを通過する必要があります。

ひっくり返して、最年長の従業員が所有者であるとしましょう。彼が会社に何かをしてほしいとき、彼は自分でそれをしません。彼はコマンドをチェーンに送ります。各レイヤーは、何をする必要があるかを変更する可能性があります。たとえば、所有者は 365 日以内に完了する必要があると言い、各マネージャーは言われた半分の時間しかないと言い、労働者はタスクを完了します。

これらの例の各「クラス」(Worker/Manager/Owner) は、同じメソッドが呼び出されたときに異なる動作をします。しかし、それらすべてに同じ基本クラスを実装させると、それらを簡単に連鎖させることができます! これは、"Chain of Responsibility"および"Decorator"パターンの変形です。

于 2013-01-17T20:16:17.713 に答える