美文网首页
面向对象特征---多态

面向对象特征---多态

作者: 小疏林er | 来源:发表于2020-04-14 23:40 被阅读0次

1、重写

(1)概念:

重写(也叫覆盖,Override)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写。
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

Animal.class

class Animal{
    String name = "animal";
    public void eat() {
        System.out.println(name+"都得吃东西");
    }
}

Cat.class

class Cat extends Animal{
    String name = "小花儿";
    public void eat() {
        System.out.println(name+"爱吃鱼");
    }
}

Dog.class

class Dog extends Animal{
    String name = "旺财";
    public void eat() {
        System.out.println(name+"爱吃肉");
    }
    public void seeDoor() {
        System.out.println(name+"会看门");
    }
}

Test_Override.class

public class Test_Override {
    public static void main(String[] args) {
        Animal a = new Animal();
        Animal b = new Cat();
        Animal c = new Dog();
        Dog d = new Dog();
        a.eat();
        b.eat();
        c.eat();
//      c.seeDoor();  编译时c被认为是Animal,而Animal中没有seeDoor方法
        d.eat();
        d.seeDoor();
    }
}

代码结果

image.png
(2)重写的规则
  • 参数列表必须完全与被重写方法的相同。(注意和重载进行区分,重载参数列表一定不同)
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
  • 构造方法不能被重写。(构造方法可以被重载!)
  • 父类的成员方法只能被它的子类重写。
  • 声明为 final 的方法不能被重写。
  • 声明为 static 的方法不能被重写,但是能够被再次声明。

简记为"两同两小一大":

两同:方法名、形参列表同;
两小:子类方法返回值要比父类的更小或者相等,子类方法声明抛出异常应比父类抛出的异常更小或者相等;
一大:子类方法访问权限应比父类方法访问权限更大或相等。

2、多态

(1)、概念:

父类的方法在子类中表现为多种形态,同一个方法调用,由于对象的不同可能会有不同的行为。

(2)、要点
  • 多态是方法的多态,不是属性的多态,多态与属性无关。
  • 多态的存在有三个必要条件:
    I. 继承:只有继承子类才能成父类(保证同一事物)。
    II. 方法重写:才能让父类的行为和子类的同一行为,表面上是一个声明,内部 在实现上不一样,叫多种形态。
    III. 父类引用指向子类对象。
  • 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
    People p = new Student();这就是父类引用指向子类对象。
(3)多态的四种表现形式
  • 方法重载:在同一个类中,同名的方法对应着不同的方法实现,它们的区别就是参数列表的不同。
  • 方法重写:主要用于父类和子类中,子类重写父类的方法,导致了不同方法实现,但是方法名和参数列表都相同。
  • 抽象类:一个类中的方法只给出了规范,但是并没有具体实现,只能由子类继承后实现。
  • 接口:接口是一个抽象类型,是抽象方法的集合。一个类只能继承一个抽象类,而一个类却可以实现多个接口。
(4)多态要注意的细节
  • 多态情况下,子父类存在同名的成员变量或同名的静态成员函数时,访问的都是父类成员,除非在同名非静态函数中调用。
  • 多态情况下,子父类存在同名的非静态的成员函数时,访问的是子类的成员函数。(这样重写才有意义)
  • 多态情况下,不能访问子类特有的成员。需要向下强制转型才可。

3、多态的应用场景

(1)多态用于形式参数类型的时候,可以接受更多类型的数据 。

例如传入多边形,计算多边形面积、周长。

public class Test_OverrideDuobian {
    public static void main(String[] args) {
        Jvxing j = new Jvxing(10,5);
        out(j);
        DengyaoTixing d =new DengyaoTixing(4,10,4,5);
        out(d);
    }
    public static void out(Duobianxing d){    //父类引用指向子类对象
        d.getLength();
        d.getArea();
    }
}
abstract class Duobianxing{
    public abstract void getLength();
    public abstract void getArea();
}
class Jvxing extends Duobianxing{
    int width;
    int height;
    public Jvxing(int width, int height) {
        super();
        this.width = width;
        this.height = height;
    }
    public void getLength() {
        System.out.println("矩形周长为:"+2*(width+height));
    }
    public void getArea() {
        System.out.println("矩形的面积为:"+width*height);
    }
}
class DengyaoTixing extends Duobianxing{
    int shangdi;
    int xiadi;
    int height;
    int xiebian;
    public DengyaoTixing(int shangdi, int xiadi, int height, int xiebian) {
        super();
        this.shangdi = shangdi;
        this.xiadi = xiadi;
        this.height = height;
        this.xiebian = xiebian;
    }
    public void getLength() {
        System.out.println("等腰梯形的周长为:"+((2*xiebian)+shangdi+xiadi));
    }
    public void getArea() {
        System.out.println("等腰梯形的面积为:"+(shangdi+xiadi)*height/2);
    }
}

结果图:

image.png

(2)多态用于返回值类型的时候,可以返回更多类型的数据。

例如通过名字获取不同子类的照片。

public class Test_OverrideYY {
    public static Photo getPhoto(String name) {
        if(name=="小花儿") {
            return new Cat();
        }else {
            return new Dog();
        }
    }
    public static void main(String[] args) {
        Photo p = getPhoto("小花儿");
        p.photoGraph();
        Photo p1 = getPhoto("旺财");
        p1.photoGraph();
    }
}
abstract class Photo{
    public abstract void photoGraph(); 
}
class Cat extends Photo{
    String name = "小花儿";
    public void photoGraph() {
        System.out.println(name+"比个耶");
    }
}
class Dog extends Photo{
    String name = "旺财";
    public void photoGraph() {
        System.out.println(name+"喊茄子");
    }
}

结果图:

image.png

相关文章

网友评论

      本文标题:面向对象特征---多态

      本文链接:https://www.haomeiwen.com/subject/ljpamhtx.html