• 实现多态的方式——抽象类


    2、抽象类

      抽象类的特点:

      1)、抽象类中的抽象成员必须标记为abstract,并且不能有任何实现。

          方法不能有任何实现是指,方法没有大括号,也没有方法体。

          只有大括号,没有方法体的方法叫做空实现。

      2)、抽象成员必须标记在抽象类中

      3)、抽象类是有构造函数的,但抽象类不能被实例化

      4)、子类继承抽象类后,必须把父类中的所有抽象成员都重写。(除非子类也是一个抽象类,则可以不重写)

          注意:在重写抽象成员的时候,必须在前面加上override标记,否则编译器会报错。用虚方法实现多态的话,也要加上override标记,但省略override,编译器不会报错。

      5)、抽象成员的访问修饰符不能是private

      6)、在抽象类中可以包含实例成员,并且它们可以不被子类实现

      7)、如果父类的抽象方法中有参数。那么,继承这个抽象父类的子类在重写父类的方法的时候,必须传入对应的的参数。

          如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候,也必须要写上返回值。

         也就是说,子类在重写抽象父类的抽象方法的时候,必须保证方法的签名与父类的方法签名一致。(方法的签名:方法的参数和返回值)

       

      什么时候使用抽象类:在已有的几个类中,如果说我们可以抽象出一个父类,并且父类中必须写上这几个子类共有的一个方法,且不知道如何去写这个方法。

      圆形和矩形都有一个共同的父类:形状,但形状却是抽象的,我们无法计算它的面积和周长,所以必须写成抽象类。而圆形和矩形,它们计算面积和周长的方法也是不同的。这样,我们就必须对形状这个抽象类中,计算面积和周长的方法进行重写。

        class Program
        {
            static void Main(string[] args)
            {
                //使用多态求矩形的面积和周长以及圆形的面积和周长
                Shape shape = new Square(5, 6); //new Circle(5);
                double area = shape.GetArea();
                double perimeter = shape.GetPerimeter();
                Console.WriteLine("这个形状的面积是{0},周长是{1}", area, perimeter);
                Console.ReadKey();
    
            }
        }
    
        public abstract class Shape
        {
            public abstract double GetArea();
            public abstract double GetPerimeter();
        }
        public class Circle : Shape
        {
            private double _r;
            public double R
            {
                get { return _r; }
                set { _r = value; }
            }
    
            public Circle(double r)
            {
                this.R = r;
            }
            public override double GetArea()
            {
                return Math.PI * this.R * this.R;
            }
    
            public override double GetPerimeter()
            {
                return 2 * Math.PI * this.R;
            }
        }
    
        public class Square : Shape
        {
            private double _height;
            public double Height
            {
                get { return _height; }
                set { _height = value; }
            }
    
            private double _width;
            public double Width
            {
                get { return _width; }
                set { _width = value; }
            }
    
            public Square(double height, double width)
            {
                this.Height = height;
                this.Width = width;
            }
    
            public override double GetArea()
            {
                return this.Height * this.Width;
            }
    
            public override double GetPerimeter()
            {
                return (this.Height + this.Width) * 2;
            }
        }

      抽象类也可以包含抽象的属性,因为属性的本质是 get、set这两个方法。

        class Program
        {
            static void Main(string[] args)
            {
                //狗狗会叫 猫咪会叫
    
                Animal a = new Cat();//new Dog();
                a.Bark();
                
                Console.ReadKey();
            }
        }
    
        public abstract class Animal
        {
            public Animal(int age)
            {
                this.Age = age;
            }
    
            public virtual void T()
            {
                Console.WriteLine("动物有声明");
            }
    
            private int _age;
            public int Age
            {
                get { return _age; }
                set { _age = value; }
            }
    
            //Bark()没有任何实现
            public abstract void Bark();
    
            public abstract string Name
            {
                get;
                set;
            }
    
            //Test()只有大括号,没有方法体,是空实现
            public void Test()
            {
                //空实现
            }
        }
    
        public class Dog : Animal
        {
            public override void Bark()
            {
                Console.WriteLine("狗狗旺旺的叫");
            }
    
            public override string Name
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
        }
    
        public class Cat : Animal
        {
            public override void Bark()
            {
                Console.WriteLine("猫咪喵喵的叫");
            }
    
            public override string Name
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
        }

    关于抽象类需要注意的几点:

      1)需要用abstract关键字标记

      2)抽象方法不能有任何方法实现

      3)抽象成员必须包含在抽象类中

      4)由于抽象成员没有任何实现,所以子类必须将抽象成员重写(以override来标记)。

      5)抽象类不能被实例化

      6)抽象类的作用:为了让子类继承

      7)抽象方法不能用static修饰  

        因为:抽象方法是没有任何方法实现的,如果直接通过类名来调用,这样的方法无法执行,没有任何意义;

           能调用抽象方法的只能是重写了抽象方法的子类的对象(如果抽象类的子类也是抽象类的话,就无法调用)

  • 相关阅读:
    20145105 《Java程序设计》第4周学习总结
    调查问卷
    20145105 《Java程序设计》第3周学习总结
    20145105 《Java程序设计》实验一总结
    20145105 《Java程序设计》第5周学习总结
    【linux配置】VMware安装Redhat6.5
    【eclipse】解决:eclipse或STS运行maven工程出现Missing artifact jdk.tools:jdk.tools:jar:1.7问题
    【linux配置】在VMware中为Redhat HAT配置本地yum源
    【linux配置】虚拟机配置静态IP地址
    【linux配置】Linux系统下安装rz/sz命令以及使用说明
  • 原文地址:https://www.cnblogs.com/lcxBlog/p/4886385.html
Copyright © 2020-2023  润新知