zoukankan      html  css  js  c++  java
  • 继承、多态、接口

    一、继承
    1、基类和派生类

    C# 不支持类的多重继承。但是支持接口的多重继承。
    继承是可以传递的。定义要从其他类派生的类时,派生类会隐式获得基类的所有成员(除了其构造函数和终结器)。派生类因而可以重用基类中的代码,而无需重新实现。在派生类中,可以添加更多成员。通过这种方法,派生类可扩展基类的功能。

    示例:

    using System;
    using System.Diagnostics;
    
    namespace Test
    {
        class Program
        {
            class Shape
            {
                protected int _height;
                protected int _weight;
                public void SetHeight(int h) => _height = h;
                public void SetWeight(int w) => _weight = w;
            }
    
            class Rectangle : Shape
            {
                public int GetArea()
                {
                    return _height * _weight;
                }
            }
            static void Main(string[] args)
            {
                Rectangle obj = new Rectangle();
                obj.SetHeight(10);
                obj.SetWeight(20);
                Console.WriteLine($"Area={obj.GetArea()}");
                Console.ReadLine();
            }
        }
    }
    View Code

    2、基类的初始化

    派生类继承了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前被创建。可以在成员初始化列表中进行父类的初始化。

    示例:

    using System;
    using System.Diagnostics;
    
    namespace Test
    {
        class Program
        {
            class Shape
            {
                protected int _height;
                protected int _weight;
                public Shape() { }
                public Shape(int h, int w) { _height = h;_weight = w; }
                public void SetHeight(int h) => _height = h;
                public void SetWeight(int w) => _weight = w;
            }
    
            class Rectangle : Shape
            {
                public Rectangle():base(10, 10) { }
                public int GetArea()
                {
                    return _height * _weight;
                }
            }
            static void Main(string[] args)
            {
                Rectangle obj = new Rectangle();
                Console.WriteLine($"Area={obj.GetArea()}");
                Console.ReadLine();
            }
        }
    }
    View Code

    二、多态

    多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。

    1、静态多态性

    在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为:函数重载、运算符重载。

    2、动态多态性

    动态多态性是通过抽象类和虚方法实现的。

    抽象方法和虚方法的区别:

    • 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
    • 抽象方法只能在抽象类中声明,虚方法不是。如果类包含抽象方法,那么该类也是抽象的,也必须声明类是抽象的。
    • 抽象方法必须在派生类中重写,这一点和接口类似。虚方法是已经实现了的,可以被子类覆盖,也可以不覆盖,取决于需求。

    1)抽象类

    用关键字 abstract 创建抽象类,用于提供接口的部分类的实现。当一个派生类继承自该抽象类时,实现即完成。抽象类包含抽象方法,抽象方法可被派生类实现。派生类具有更专业的功能。

    抽象类的一些规则:

    • 您不能创建一个抽象类的实例。
    • 您不能在一个抽象类外部声明一个抽象方法。
    • 通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。

    示例:

    using System;
    using System.Diagnostics;
    
    namespace Test
    {
        class Program
        {
            public abstract class Shape
            {
                protected int _x;
                protected int _y;
                public Shape(int x, int y) { _x = x;_y = y; }
                public abstract void Area();
            }
    
            class Rectangle : Shape
            {
                public Rectangle():base(10, 10) { }
                public override void Area()
                {
                    Console.WriteLine($"Rectangle 类的面积:{_x * _y}");
                }
            }
    
            class Square : Shape
            {
                public Square() : base(20, 20) { }
                public override void Area()
                {
                    Console.WriteLine($"Square 类的面积:{_x * _y}");
                }
            }
    
            public static void ShowArea(Shape obj)
            {
                obj.Area();
            }
    
            static void Main(string[] args)
            {
                ShowArea(new Rectangle());
                ShowArea(new Square());
                Console.ReadLine();
            }
        }
    }
    View Code

    2)虚方法

    当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。虚方法是使用关键字 virtual 声明的。虚方法可以在不同的继承类中有不同的实现。对虚方法的调用是在运行时发生的。

    示例:

    using System;
    using System.Diagnostics;
    
    namespace Test
    {
        class Program
        {
            public class Shape
            {
                protected int _x;
                protected int _y;
                public Shape(int x, int y) { _x = x;_y = y; }
                public virtual void Area()
                {
                    Console.WriteLine($"Shape 类的面积:{_x * _y}");
                }
            }
    
            class Rectangle : Shape
            {
                public Rectangle():base(10, 10) { }
                public override void Area()
                {
                    Console.WriteLine($"Rectangle 类的面积:{_x * _y}");
                }
            }
    
            class Square : Shape
            {
                public Square() : base(20, 20) { }
                public override void Area()
                {
                    Console.WriteLine($"Square 类的面积:{_x * _y}");
                }
            }
    
            public static void ShowArea(Shape obj)
            {
                obj.Area();
            }
    
            static void Main(string[] args)
            {
                ShowArea(new Rectangle());
                ShowArea(new Square());
                Console.ReadLine();
            }
        }
    }
    View Code

    三、接口

    接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
    接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
    接口及其成员总是隐式为public的。
    接口使用的注意事项:

    • 接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
    • 接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
    • 实现接口时,必须和接口的格式一致。
    • 必须实现接口的所有方法。

    示例:

    using System;
    using System.Diagnostics;
    
    namespace Test
    {
        class Program
        {
            public interface IShape
            {
                int GetHeight { get; set; }
                int GetWeight { get; set; }
                void GetArea();
            }
    
            public class Rectangle : IShape
            {
                private int _height;
                private int _weight;
                public int GetHeight { get => _height; set => _height=value; }
                public int GetWeight { get => _weight; set => _weight=value; }
    
                public void GetArea()
                {
                    Console.WriteLine($"Rectangle: Area={_height * _weight}");
                }
            }
    
            public class Square : IShape
            {
                private int _height;
                private int _weight;
                public int GetHeight { get => _height; set => _height = value; }
                public int GetWeight { get => _weight; set => _weight = value; }
    
                public void GetArea()
                {
                    Console.WriteLine($"Square: Area={_height * _weight}");
                }
            }
    
            public static void Show(IShape obj)
            {
                obj.GetArea();
            }
    
            static void Main(string[] args)
            {
                Rectangle rect = new Rectangle();
                rect.GetHeight = 10;
                rect.GetWeight = 10;
                Show(rect);
                Square sq = new Square();
                sq.GetHeight = 20;
                sq.GetWeight = 20;
                Show(sq);
                Console.ReadLine();
            }
        }
    }
    View Code

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/ACGame/p/10963025.html
Copyright © 2011-2022 走看看