面向对象特征---继承

2020-04-22  本文已影响0人  小疏林er

1、继承

继承是面向对象三大特征之一(继承、封装、多态),也是实现软件复用的重要手段。

继承就是子类继承父类的(非私有)特征和行为,使得子类对象(实例)具有父类的实例域(实例变量)和方法,或子类从父类继承方法,使得子类具有父类相同的行为,并且可以拥有自己的属性和方法,以此来对父类进行扩展。

  • 注:子类使用从父类继承过来的方法的时候,优先使用父类属性(除非子类将父类相同属性进行覆盖时,子类调用重写后的方法,才会使用自己覆盖后的属性,子类从没真正拥有过父类的属性,覆盖以后才算拥有)。

2、继承的特性

  • 子类是对父类的扩展,子类是一种特殊的父类。
  • Java类只能有一个直接父类,实际上可以有无限多的间接父类(桃子-->水果-->食物-->物品)。
  • 子类拥有父类非私有的属性、方法,也可以拥有自己的属性和方法(子类扩展了父类)。
  • 子类可以重写父类的方法。

:重写的要求简记为"两同两小一大":

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

3、extends和implements

  • extends:Java中把extends作为继承的关键字(本意是扩展,子类是对父类的扩展),类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。但是接口可以多继承(interface C extends A, B {})。
  • implements:implements关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔,class A implements B,C,D,E,F,G)。

4、super和this

  • super:通过super关键字来实现对父类成员的访问,用来引用当前对象的父类(在子类方法中调用父类被覆盖的方法)。
    子类不继承父类的构造器,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。
    super.:代表当前对象的父类对象
    super():代表当前对象的父类无参构造器
  • this:根据出现位置的不同,有两种情况。
    (1)在构造器中引用该构造器正在初始化的对象。
    (2)在方法中引用调用该方法的对象。
    this.:代表当前对象
    this():代表当前对象的无参构造器
  • super()this()不能同时出现在同一个构造器中。
  • super()this() 必须出现在构造器的第一行。

5、构造器

构造器最大的用处就是在创建对象时执行初始化,当创建一个对象时,系统会为这个对象的实例进行默认的初始化(默认基本类型的数值变量设为0,布尔类型设为false,引用类型设为null)。如果想改变这种默认的初始化,就可以通过自定义构造器来实现(重载)。
修饰符 构造器名(形参列表){构造器执行体}

  • 修饰符:可以省略,也可以是public、protected、private之一;
  • 构造器名:构造器名必须与类名相同
  • 形参列表:和定义方法形参列表的格式完全相同。
  • 作用:
    用来配合创建new类的对象的。
    代码主要用来实现对象的属性初始化。
  • 所有类都必须提供构造器,如果类中没有主动声明构造器,则系统自动默认提供一个无参无内容的构造器。
  • 构造器既不能定义返回值类型,也不能使用void声明构造器没有返回值!,加了返回值虽然不报错但是,它就是普通方法了,不是构造方法。实际上,构造器是有返回值的,只不过是隐式的,它会返回调用它这个类的实例(其实是一个指向这个实例的堆地址),不写返回值就可以区分正常方法和构造器了。

考:

class A{
 public A(int a){

 }
}

class B extends A{
 public B(){      //这行报错了,相当于下面一行自动补了一个super(),但是父类只有有参构造器,所以报错了。
       
 }
}

举一个栗子:

鸟类有品种、重量、简介三个属性和一个fly方法,其中简介设成私有类型的了,鸵鸟继承了鸟类,它就获得了品种和重量属性,fly方法。其中简介是私有类型的属性,所以它不能继承过来,又因为它不会飞,又对fly方法进行了重写。

Bird .class

public class Bird {
    String variety;     //品种,包访问权限
    float weight;
    private String introduction;  //鸟类的简介,子类没必要继承所以设成私有的
    //构造方法(构造器)
    public Bird(String variety, float weight) {
        super();
        this.variety = variety;
        this.weight = weight;
    }       //重量
    
    public void fly() {
        System.out.println("我可以在天上飞!");
    }
    
}

Ostrich.class

public class Ostrich extends Bird{
    
    //新增加了父类没有的属性,扩展了父类,并且设成了私有类型,通过get、set方法操作他们
    private String name;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    //子类自己的构造方法,里面调用了父类的含参构造器
    public Ostrich(String variety, float weight, String name) {
        super(variety, weight);  //通过super显式调用父类含参构造器(配以合适参数)
        this.name = name;
    }
    
    @Override  //因为鸵鸟不会飞,重写了fly方法
    public void fly() {
        System.out.println("我叫"+this.name+",我是一只"+this.variety+",俺不会飞,只能跑!");
        super.fly();     //使用super关键字调用父类被覆盖的fly方法。
    }
    
    public static void main(String[] args) {
        Ostrich o = new Ostrich("鸵鸟", 5.0f, "小花");    //这时候就调用了构造器,返回了一个对象地址给o
        o.fly();
//      o.introduction="啦啦啦";   子类没有继承父类私有属性,所以不能使用introduction
    }

}
image.png
上一篇下一篇

猜你喜欢

热点阅读