• C# 语言的面向对象技术


    C# 语言的面向对象技术

    知识结构:

    图1 知识结构


    1、类与对象

    1.1 抽象数据类型(Abstract Data Type)的概念

    抽象数据类型由一组数据以及在该组数据上的一组操作组成。

    抽象数据类型的格式定义如下:

    ADT Name is
        Data
            构成该抽象数据类型所必须的基本数据项
        Operations
            Constructor
                Initial Values:赋给基本数据项的值
                Press:初始化对象
            Operation1
                Input:操作1要求用户输入的值
                PreCondition:系统执行操作1前的数据状态
                Press:操作1的解释说明
                Output:操作1结束后返回的数据
                PostCondition:系统执行操作1后的数据状态
            Operation2
                … …
            OperationN
                … …
    End ADT Name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    例如:矩形结构的ADT描述。

    ADT Rectangle is
        Data
            float Length
            float Width
        Operations
            Constructor
                Initial Values:构造矩形时,赋长和宽的值。
                Press:初始化对象,给矩形的长和宽赋值。
            SetLength
                Input:赋给变量Length的新值
                PreCondition:无
                Press:将矩形的长度值修改为新值
                Output:无
                PostCondition:矩形的长度值被修改
            SetWidth
                Input:赋给变量Width的新值
                PreCondition:无
                Press:将矩形宽度值修改为新值
                Output:无
                PostCondition:矩形的宽度值被修改
            GetArea
                Input:无
                PreCondition:矩形的长度和宽度都大于零
                Press:得到矩形的面积
                Output:返回矩形面积的值
                PostCondition:无
            GetPerimeter
                Input:无
                PreCondition:矩形的长度和宽度都大于零
                Press:得到矩形的周长
                Output:返回矩形的周长
                PostCondition:无
    End ADT Rectangle
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    一旦定义了矩形结构的ADT描述,就可以用代码进行实现了。

    public class Rectangle
    {
        public float Length;
        public float Width;
        public Rectangle(float length, float width)
        {
            Length = length > 0 ? length : 0f;
            Width = width > 0 ? width : 0f;
        }
        public void SetLength(float length)
        {
            Length = length > 0 ? length : 0f;
        }
        public void SetWidth(float width)
        {
            Width = width > 0 ? width : 0f;
        }
        public float GetArea()
        {
            if (Length * Width == 0)
                throw new ArgumentOutOfRangeException("长度或宽度为零。");
            return Length * Width;
        }
        public float GetPerimeter()
        {
            if (Length * Width == 0)
                throw new ArgumentOutOfRangeException("长度或宽度为零。");
            return (Length + Width) * 2;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    1.2 类与对象的概念

    • 类:用高级程序语言实现的一个ADT描述。
    • 对象:通过类声明的变量。

    2、封装

    2.1 什么是封装

    把类的内部隐藏起来以防止外部看到内部的实现过程。

    2.2 怎样封装

    • 通过限制修饰符privateprotectedpublicinternal来实现。
    • 对类中的数据(Data)和操作(Operation)的限制修饰符:
      • private:只允许类的内部访问(默认)。
      • protected:只允许类的内部和子类访问。
      • public:类的内部与外部都可以访问。
      • internal:在同一程序集内部访问,相当于public
    • 对类的限制修饰符:
      • public:都可以使用。
      • internal:在同一程序集内部使用(默认)。

    注:internal修饰的类,方法或属性,只要是在同一个程序集中的其它类都可以访问,如果二者不在同一命名空间,只要使用using引用上相应的命名空间即可,这里,从另外一个方面也间接看出命名空间并不是界定访问级别的,而是保证全局的类唯一性的。

    参考图文:

    2.3 怎样表示

    • 类图(Class Diagram)
      • -:private
      • +:public
      • #:protected

    图2 Class Diagram

    例子:根据下列类图实现Animal类型。

    图3 Class Diagram

    public class Animal
    {
        public int Age;
        public double Weight;
        public void Eat()
        {
            Console.WriteLine("Animal Eat.");
        }
        public void Sleep()
        {
            Console.WriteLine("Animal Sleep.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Animal();
            al.Eat();// Animal Eat.
            al.Sleep();// Animal Sleep.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、继承

    3.1 什么是继承

    子类拥有父类某些Data和Operation的过程。

    3.2 怎样继承

    public class Child : Parent
    { 
        //… 
    }
    
    • 1
    • 2
    • 3
    • 4
    • Child:子类(派生类),Parent:父类(基类)
    • 在类的声明中,利用“:”表示继承。
    • C# 只支持单继承,但可以定义一个不允许其它类继承的类。
    public sealed class Name
    {
        //...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 利用sealed关键字可防止所声明的类被继承。

    子类与父类中数据与操作的继承关系:

    • 父类 public protected private internal
    • 子类 public protected 无法继承 internal

    3.3 子类怎样访问父类成员

    利用base关键字。

    例子:子类访问父类且父类构造函数不带参数。

    public class Parent
    {
        private int _data1; // 只能被类的内部访问
        protected int Data2; // 能被子类访问和继承
        public int Data3; // 能被子类访问和继承
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Child : Parent
    {
        public Child()
        {
            base.Data2 = 2;
            base.Data3 = 3;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    class Program
    {
        static void Main(string[] args)
        {
            Child cld = new Child();
            Console.WriteLine(cld.Data3); // 3
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    例子:子类访问父类且父类构造函数带参数。

    public class Parent
    {
        private int _data1; // 只能被类的内部访问
        protected int Data2; // 能被子类访问和继承
        public int Data3; // 能被子类访问和继承
        public Parent(int dt1, int dt2, int dt3)
        {
            _data1 = dt1;
            Data2 = dt2;
            Data3 = dt3;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    public class Child : Parent
    {
        public Child() : base(0, 2, 3)
        {
            ;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    class Program
    {
        static void Main(string[] args)
        {
            Child cld = new Child();
            Console.WriteLine(cld.Data3);// 3
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.4 怎样表示

    • 通过类图来表示

    图4 继承关系

    例子:根据类图实现程序代码,注意类之间的继承关系。

    图5 Class Diagram

    public class Animal
    {
        public int Age;
        public double Weight;
        public void Eat()
        {
            Console.WriteLine("Animal Eat.");
        }
        public void Sleep()
        {
            Console.WriteLine("Animal Sleep.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    public class Bird : Animal
    {
        public void Fly()
        {
            Console.WriteLine("Bird Fly.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Dog : Animal
    {
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Fish : Animal
    {
        public void Swim()
        {
            Console.WriteLine("Fish Swim.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    class Program
    {
        static void Main(string[] args)
        {
            Dog dog = new Dog();
            dog.Run(); //Dog Run.
            Bird bird = new Bird();
            bird.Fly(); //Bird Fly.
            Fish fish = new Fish();
            fish.Swim(); //Fish Swim.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.5 实例化

    为对象分配存储空间的过程。

    例子:类的实例化。

    public class Animal
    {
        public int Age;
        public double Weight;
        public void Eat()
        {
            Console.WriteLine("Animal Eat.");
        }
        public void Sleep()
        {
            Console.WriteLine("Animal Sleep.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    public class Dog : Animal
    {
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Animal(); // 实例化Animal
            al.Eat(); // Animal Eat.
            al.Sleep(); // Animal Sleep.
    
            Dog dg = new Dog(); // 实例化Dog
            dg.Age = 2;
            dg.Weight = 4.5;
            Console.WriteLine("Dog Infor: Age:{0}, Weight:{1}", dg.Age, dg.Weight);
            // Dog Infor: Age:2, Weight:4.5
            dg.Sleep(); // Animal Sleep.
            dg.Eat(); // Animal Eat.
            dg.Run(); // Dog Run.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    例子:子类与父类有重名方法。

    图6 Class Diagram

    public class Animal
    {
        public int Age;
        public double Weight;
    
        public void Eat()
        {
            Console.WriteLine("Animal Eat.");
        }
    
        public void Sleep()
        {
            Console.WriteLine("Animal Sleep.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    public class Dog : Animal
    {
        public void Eat()
        {
            Console.WriteLine("Dog Eat.");
        }
    
        public void Sleep()
        {
            Console.WriteLine("Dog Sleep.");
        }
    
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Dog(); // 子类可以实例化父类
            al.Eat(); // Animal Eat.(重名方法存在问题)
            al.Sleep(); // Animal Sleep.
    
            Dog dg = al as Dog; //强制类型转换或Dog dg = (Dog)al;
            dg.Eat(); // Dog Eat.
            dg.Sleep(); // Dog Sleep.
            dg.Run(); // Dog Run.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意:

    • Animal al = new Dog();(正确)
    • Dog dg = new Animal();(错误)

    子类可以实例化父类,而父类不可以实例化子类,即:Dog一定是Animal,而Animal不一定是Dog

    • Animal al = new Dog();
    • Dog dg = al;(错误)需要强制类型转换。
    • Dog dg = al as Dog; (正确)若al不是Dog类型,返回null。
    • Dog dg = (Dog)al; (正确)若al不是Dog类型,系统会抛出异常。

    4、多态

    4.1 什么是多态

    相同的操作(Operation),对于不同的对象,可以有不同的解释,产生不同的执行结果。

    4.2 多态的分类

    • 运行时多态:在运行时决定执行哪个类的哪个方法。(override覆写)
    • 编译时多态:在编译时决定执行类中的哪个方法。(overload重载)

    4.3 多态的实现

    运行时多态:

    • 在父类中定义并实现虚方法(virtual)。
    • 在子类中覆写(override)该虚方法。
    • 虚方法必须有方法体。
    • 覆写虚方法,要求方法名,形参,返回值类型必须相同。

    例子:实现运行时多态的代码

    图7 Class Diagram

    public class Animal
    {
        public int Age;
        public double Weight;
    
        public virtual void Eat()
        {
            Console.WriteLine("Animal Eat.");
        }
    
        public virtual void Sleep()
        {
            Console.WriteLine("Animal Sleep.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog Eat.");
        }
    
        public override void Sleep()
        {
            Console.WriteLine("Dog Sleep.");
        }
    
        public virtual void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Dog();
            //在执行时,通过判断al的类型来决定执行哪个类中的哪个方法;
            al.Eat(); // Dog Eat.
            al.Sleep(); // Dog Sleep.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    编译时多态:

    • 类中定义的方法或操作符可能有不同的版本。
    • 操作符重载:operator关键字
    • public static 类型 operator 运算符(形参列表){ … }
    • 方法重载:必须有相同的方法名、必须有不同的参数列表、可以有相同的返回值类型

    例子:通过类图实现编译时多态的代码

    图8 Class Diagram

    public class Complex
    {
        public int A;
        public int B;
    
        public Complex(int a, int b)
        {
            this.A = a; //this表示在内存中Complex对象
            this.B = b;
        }
    
        public static Complex operator +(Complex c1, Complex c2)
        {
            return new Complex(c1.A + c2.A, c1.B + c2.B);
        }
    
        public override string ToString()
        {
            return string.Format("{0}+{1}i", A, B);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public class Math
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    
        public double Add(double x, double y)
        {
            return x + y;
        }
    
        public Complex Add(Complex x, Complex y)
        {
            return x + y;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    class Program
    {
        static void Main(string[] args)
        {
            Complex c1 = new Complex(1, 2);
            Complex c2 = new Complex(3, 4);
            Complex c3 = c1 + c2;
            Console.WriteLine("C1={0}", c1); // C1=1+2i
            Console.WriteLine("C2={0}", c2); // C2=3+4i
            Console.WriteLine("C3={0}", c3); // C3=4+6i
            Math mth = new Math();
            Complex c4 = mth.Add(c2, c3);
            //在编译时,根据参数列表决定执行哪个类中的哪个方法;
            Console.WriteLine("C4={0}", c4); // C4=7+10i
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    总结:overrideoverload

    -override(覆写)overload(重载)
    位置子类与父类的关系中同一类中
    方法名相同相同
    参数列表相同不相同
    返回值类型相同可以相同

    4.4 抽象方法与抽象类

    • 抽象方法:可以看成没有实现体的虚方法(abstract),即只有方法的声明,需要在子类中覆写(override)该方法。
    • 抽象类:含有抽象方法的类。抽象类不可以直接实例化对象。

    例9:根据类图实现代码

    图9 Class Diagram

    public abstract class Animal
    {
        public int Age;
        public double Weight;
        public abstract void Eat();
        public abstract void Sleep();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog Eat.");
        }
        public override void Sleep()
        {
            Console.WriteLine("Dog Sleep.");
        }
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Dog();
            al.Eat(); // Dog Eat.
            al.Sleep(); // Dog Sleep.
            ((Dog)al).Run(); // Dog Run.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注意:

    • al.Run();(错误)
    • ((Dog)al).Run();(正确)

    抽象类中并没有Run方法,如果使用需要强制类型转换。

    • Animal al = new Animal ();(错误)

    抽象类不可以直接实例化对象,系统会抛出异常。

    总结:抽象方法和虚方法

    -抽象方法虚方法
    在父类中没有实现体(abstract必须有实现体(virtual
    在子类中必须覆写(override可以覆写也可以不覆写(override

    例子:饲养系统

    某饲养员(Raiser)在目前状态下需要饲养三种动物:狗(Dog)、鸟(Bird)和鱼(Fish),该三种动物只需要让其睡觉(Sleep)和吃饭(Eat)即可。

    请设计该饲养系统,要求满足软件设计的“开闭原则”。

    方案一:

    图10 Class Diagram

    public class Bird
    {
        public void Eat()
        {
            Console.WriteLine("Bird Eat.");
        }
        public void Sleep()
        {
            Console.WriteLine("Bird Sleep.");
        }
        public void Fly()
        {
            Console.WriteLine("Bird Fly.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    public class Dog
    {
        public void Eat()
        {
            Console.WriteLine("Dog Eat.");
        }
        public void Sleep()
        {
            Console.WriteLine("Dog Sleep.");
        }
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    public class Fish
    {
        public void Eat()
        {
            Console.WriteLine("Fish Eat.");
        }
        public void Sleep()
        {
            Console.WriteLine("Fish Sleep.");
        }
        public void Swim()
        {
            Console.WriteLine("Fish Swim.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    public class Raiser
    {
        public void RaiseDog()
        {
            Dog dog = new Dog();
            dog.Eat();
            dog.Sleep();
        }
        public void RaisBird()
        {
            Bird bird = new Bird();
            bird.Eat();
            bird.Sleep();
        }
        public void RaisFish()
        {
            Fish fish = new Fish();
            fish.Eat();
            fish.Sleep();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    class Program
    {
        static void Main(string[] args)
        {
            Raiser rar = new Raiser();
            rar.RaiseDog();
            // Dog Eat.
            // Dog Sleep.
            rar.RaisBird();
            // Bird Eat.
            // Bird Sleep.
            rar.RaisFish();
            // Fish Eat.
            // Fish Sleep.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    方案二:

    图11 Class Diagram

    public class Bird
    {
        public void Eat()
        {
            Console.WriteLine("Bird Eat.");
        }
    
        public void Sleep()
        {
            Console.WriteLine("Bird Sleep.");
        }
    
        public void Fly()
        {
            Console.WriteLine("Bird Fly.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Dog
    {
        public void Eat()
        {
            Console.WriteLine("Dog Eat.");
        }
    
        public void Sleep()
        {
            Console.WriteLine("Dog Sleep.");
        }
    
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Fish
    {
        public void Eat()
        {
            Console.WriteLine("Fish Eat.");
        }
    
        public void Sleep()
        {
            Console.WriteLine("Fish Sleep.");
        }
    
        public void Swim()
        {
            Console.WriteLine("Fish Swim.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public enum AnimalType
    {
        Dog,
        Bird,
        Fish
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Raiser
    {
        public void Raise(AnimalType alt)
        {
            switch (alt)
            {
                case AnimalType.Bird:
                    Bird bird = new Bird();
                    bird.Eat();
                    bird.Sleep();
                    break;
                case AnimalType.Dog:
                    Dog dog = new Dog();
                    dog.Eat();
                    dog.Sleep();
                    break;
                case AnimalType.Fish:
                    Fish fish = new Fish();
                    fish.Eat();
                    fish.Sleep();
                    break;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    class Program
    {
        static void Main(string[] args)
        {
            Raiser rar = new Raiser();
            rar.Raise(AnimalType.Dog);
            // Dog Eat.
            // Dog Sleep.
            rar.Raise(AnimalType.Bird);
            // Bird Eat.
            // Bird Sleep.
            rar.Raise(AnimalType.Fish);
            // Fish Eat.
            // Fish Sleep.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    方案三:

    图12 Class Diagram

    public abstract class Animal
    {
        public int Age;
        public double Weight;
        public abstract void Eat();
        public abstract void Sleep();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Bird : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Bird Eat.");
        }
    
        public override void Sleep()
        {
            Console.WriteLine("Bird Sleep.");
        }
    
        public void Fly()
        {
            Console.WriteLine("Bird Fly.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog Eat.");
        }
    
        public override void Sleep()
        {
            Console.WriteLine("Dog Sleep.");
        }
    
        public void Run()
        {
            Console.WriteLine("Dog Run.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Fish : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Fish Eat.");
        }
    
        public override void Sleep()
        {
            Console.WriteLine("Fish Sleep.");
        }
    
        public void Swim()
        {
            Console.WriteLine("Fish Swim.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Raiser
    {
        public void Raise(Animal al)
        {
            al.Eat();
            al.Sleep();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    class Program
    {
        static void Main(string[] args)
        {
            Raiser rsr = new Raiser();
            rsr.Raise(new Dog());
            // Dog Eat.
            // Dog Sleep.
            rsr.Raise(new Bird());
            // Bird Eat.
            // Bird Sleep.
            rsr.Raise(new Fish());
            // Fish Eat.
            // Fish Sleep.
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    【考研数学】概率论如何复习?跟谁好?
    Web Tour Server窗口闪现
    关于Nacos启动报错 Unable to start embedded Tomcat
    git上登录拉取项目记录
    golang中的信号量的实现原理
    学习大数据,所需要的linux基础(1)
    Zabbix出现 404Not FoundThe requested URL /zabbix was not found on this server.
    oh my zsh 失效 与 nvm 安装
    生成式人工智能(AIGC):开发者的得力助手还是职业威胁?
    成为比开发更硬气的测试人,我都经历了什么?
  • 原文地址:https://blog.csdn.net/LSGO_MYP/article/details/125598291