C# 实例化构造函数与访问器中的默认值

C# 实例化构造函数与访问器中的默认值,c#,visual-studio-2010,oop,class,C#,Visual Studio 2010,Oop,Class,我已经用C#(以及其他一些语言)编程一段时间了,但最近我决定开始编写自定义类,以便更好地理解面向对象编程。为此,我从Vehicle的一个基类和一些派生类开始研究继承 我在这里要做的是在Vehicle的base cals中设置一些默认值和逻辑,同时让派生类实现一些确定差异的信息。例如,当我在基类中设置_wheelsNumber、_motorType和_horsePower变量和逻辑时,我会让每个类(汽车、卡车、半挂车、轻便摩托车等)设置其_wheelsNumber并触发逻辑流以计算出其余属性 然而

我已经用C#(以及其他一些语言)编程一段时间了,但最近我决定开始编写自定义类,以便更好地理解面向对象编程。为此,我从Vehicle的一个基类和一些派生类开始研究继承

我在这里要做的是在Vehicle的base cals中设置一些默认值和逻辑,同时让派生类实现一些确定差异的信息。例如,当我在基类中设置_wheelsNumber、_motorType和_horsePower变量和逻辑时,我会让每个类(汽车、卡车、半挂车、轻便摩托车等)设置其_wheelsNumber并触发逻辑流以计算出其余属性

然而,我不确定我是否以正确的方式构建了我的类来实现这些目标。我不清楚我是否远程使用construcor和get/set访问器做了正确的事情(因为我不希望用户选择像一辆车有多少个轮子这样的事情,我没有声明set访问器)。我想我注意到的一件事是,用户必须在电机类型和马力之前向程序询问车轮的数量。我想这是因为它们不是在构造函数中计算的,但我不确定

任何人都将不胜感激

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;
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间车辆类
{
抽象公共类车辆
{
保护常数int smallMotor=1;
保护常数int mediumMotor=3;
受保护的警用大马达=5;
受保护的警员内的largerMotor=7;
受保护常数int hugeMotor=9;
电机保护常数=9001;
公共车辆()
{
_马力=(_motorType*_motorType)*8;
}
受保护的内车轮数量;
公共内部车轮数目
{
得到
{
返回轮数;
}
}
受保护的int_电机类型;
公共int车型
{
得到
{
如果(_轮数<4)
{
_电机类型=小型电机;
}
否则,如果(车轮数>=4和车轮数6和车轮数<10)
{
_电机类型=大型电机;
}
否则,如果(车轮数量>=10和车轮数量<18)
{
_电机类型=大型电机;
}
否则,如果(车轮数量>=18)
{
_电机类型=巨型电机;
}
其他的
{
_电机类型=错误电机;
}                
返回类型;
}
}
受保护的整数马力;
公共整数马力
{
得到
{
返回马力;
}
}
}
}

这是一种常见的继承错误应用。子类应该扩展行为,而不仅仅是修改state的值

在您的示例中,只有一个自由变量,即车轮数。其他一切都是基于此衍生出来的特质。更改vehicle的构造函数以车轮数作为参数,然后(如果需要)可以向类添加公共静态方法,如“CreateMotorcycle()”,以创建车轮数正确的车辆

备选建议练习 正如我前面提到的,当您想要扩展行为时,继承非常有用。例如,假设您有一个“Employee”基类。为了简单起见,假设每个员工有一个初级和一个高级

每当员工想要休假时,他们都必须向上级请假,但并非每个员工都能批准。请求必须在链上传递,直到到达“管理器”,这是一个派生实例

反过来说,假设最资深的员工就是所有者。当他想让公司做点什么的时候,他不会;我不能自己做。他把命令下达到链条上。每一层可能会修改需要做的事情。例如,所有者说需要在365天内完成,每个经理说他有一半的时间被告知,工人完成了任务


这些示例中的每个“类”(Worker/Manager/Owner)在调用相同的方法时表现不同。但是让它们都实现相同的基类可以很容易地将它们链接在一起!这是和模式上的一个变体。

您应该使用
enum
。您不应该使用受保护的字段;将它们转换为受保护的属性(以防您需要拦截对它们的写入,例如用于验证)。例如,正如您的代码所示,派生类可以将_wheelsumber设置为-100000@Slaks:虽然我完全同意(我想你指的是“…马达”常数),但这感觉就像用“你应该使用飞利浦螺丝刀”来回答“我想去月球”的问题。至于问题:你描述的问题太广泛和/或太模糊。有几种方法可以解决问题,但是如果不知道更多或者没有更简洁的问题,就没有办法回答。@MatthewWatson我不确定我是否理解你所说的内容。我应该用get/set访问器中如何确定它们的值的逻辑将它们重写为受保护的属性,还是简单地将它们创建为属性,这将产生不同?@WillemvanRumpt--对不起,我想我已经解释过了。我怎样才能澄清这个问题?我想,如果我理解正确的话,你是反对我使用多个派生类,因为它们没有实现基本“Vehicle”类所缺少的扩展行为,对吗?虽然我认为这是一个公平的反对意见,但我计划在我的系统中实现扩展行为