Skip to content

继承

继承

例子: Dog:name age weight strain Cat:name age weight gender 将多个类中相同的信息(属性+方法)提取出来,多个类可以共用这部分信息。 通过继承的机制来完成。

将Dog和Cat相同的信息提取到Animal,然后 让Dog和Cat继承Animal,表示继承了Animal中的信息。

java
public class Animal {
  private String name;
  private int age;
  private int weight;
  public String getName () {
    return name
  }
  public void setName (String name) {
    this.name = name
  }
  public String getAge () {
    return age
  }
  public void setAge (int age) {
    this.age = age
  }
  public String getWeight () {
    return weight
  }
  public void setWeight (int weight) {
    this.weight = weight
  }
}
java
public class Dog extends Animal {
  private String strain;
  public String getStrain () {
    return strain
  }
  public void setStrain(String strain) {
    this.strain = strain;
  }
}
java
public class Cat extends Animal {
  private String gender;
  public String getGender () {
    return gender
  }
  public void setGender(String gender) {
    this.gender = gender;
  }
}
java
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog();
    dog.setAge(3);
		System.out.println(dog.getAge());
    Cat cat = new Cat();
    cat.setGender('female');
	}
}

语法

通过extends关键字来完成 class B{

}

class A extends B{

}

子类和父类

A是子类(派生类),B是父类(超类)

一旦两个类通过extends完成关联之后,这两个类就具备了父子级的关系。

Java中的继承是代码复用(重用)的一种非常重要的方式, 优点减少代码量,方便代码的维护。

继承:一个类继承(拥有)另外一个类的属性和方法,被继承的类叫父类,继承的类叫子类。

一旦Cat和Pet建立继承关系之后,Cat类就继承了Pet类的name和age,此时在Cat类中,name,this.name,super.name表示的是同一个数据,都指向了Pet的name

直接父类

Java只支持单继承,即一个类只能拥有一个直接父类。 父类包括直接父类,间接父类。

举例: Dog-extends-> Pet-enxtends-> Animal Pet是Dog的直接父类,Animal是Pet的直接父类,Animal是Dog的简介父类。

实例化一个子类对象时,一定会优先实例化其父类对象,并且实例化父类的操作是系统自动完成,不需要我们手动去编写代码。

super

super();在子类中显式调用父类的无参构造。 super();是默认存在,不需要显式调用,跟无参构造相同,默认存在,不需要显式定义。 如果显式调用,super()必须写在第一行,否则语法错误,不能编译。

在子类中可以使用super调用方法,也可以访问属性,只能访问父类的公有(public)的信息,私有(private)是无法访问的。

1)访问属性:super.属性名

super.age = 1;

2)调用方法:super.方法名

super.test(); super.test(1,2);

3)调用构造方法:super()调用无参构造。

super();

4)super(参数列表)调用有参构造。

super(1,2);

继承和构造函数

我们通过无参构造创建子类对象时,子类的无参构造会默认调用父类的无参构造。

当我们在子类的无参构造中手动调用父类的有参构造时,会将默认的父类无参构造覆盖。

通过有参构造创建子类对象时,子类的有参构造会默认调用父类的无参构造。

当我们在子类的有参构造中手动调用父类的有参构造时,会将默认的父类无参构造覆盖。

1.调用子类无参创建对象,子类无参调用父类无参(默认) 2.调用子类无参创建对象,子类无参调用父类有参 3.调用子类有参创建对象,子类有参调用父类无参(默认) 4.调用子类有参创建对象,子类有参调用父类有参

必须写在第一行

子类的构造函数中可以通过super来访问父类的所有公有信息(属性,方法,构造方法)。

子类的普通方法中通过super可以访问属性和方法,但是不能调用构造方法。

Java中的每一个类都是一个子类(Object除外),但是不是每一个类都是父类。

super关键字使用时的注意事项:

1.super只能出现在子类的方法和构造方法中。 2.super调用构造方法时,必须写在第一行,也必须写在子类的构造方法中。 3.super不能访问父类的private的属性和方法。

super VS this

相同点:1.super和this都可以访问类中的属性,方法,构造方法。 2.super和this访问构造方法时,必须写在第一行。 3.super和this访问构造方法时,必须写在构造方法中,不能在普通方法中调用。

不同点:1.super是子类访问父类,维护两个类之间的关系, this是自己访问自己,维护一个类的关系。 2.super不能访问私有属性和方法,this可以访问私有属性和方法。

访问权限修饰符

子类不能继承父类的构造方法。

子类能继承父类的属性和方法包括:

1.使用public和protected修饰的属性和方法。 2.默认访问权限修饰符修饰的属性和方法,子类和父类必须在同一个包中。

访问权限修饰符:public protected private 默认(不用写)

子类无法继承的属性和方法:

1.private修饰的属性和方法 2.默认访问权限修饰符修饰的属性和方法,子类和父类不在同一个包中。 3.构造方法。

访问权限修饰符可以修饰属性,也可以修饰方法,描述属性或方法的可用范围

-同一个类中同一个包中父子类同一个包中非父子类不同包中父子类不同包中非父子类
private可以不可以不可以不可以不可以
默认可以可以不可以不可以不可以
protected可以可以可以可以不可以
public可以可以可以可以可以

实际开发中何时使用继承

真实世界中,如果两个对象符合 is-a 关系就可以使用继承 对象A 对象B A is a B 这句话成立,符合客观真实的逻辑关系,表示A和B符合 is-a关系,则A对应的类和B对应的类可以建立继承关系 举例: dog animal dog is a animal 成立 Dog类和Animal类可以建立继承关系 Dog继承Animal is-a 左侧的类继承右侧的类,左侧的类是子类,右侧的类是父类 animal is a dog

重写

继承中的方法重写/覆盖Override 只有在继承关系中才有重写的概念, 概念:子类根据需求对从父类继承的方法进行重新编写

父类的方法不能显示子类特有的属性时,就需要对父类方法进行重写

java
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog();
		Cat cat = new Cat();
		dog.show();
		cat.show();
	}
}
java
public class Dog extends Pet{
	public void show() {
		super.show();
		System.out.println("这是一只狗狗");
	}

}
java
public class Pet {
	public void show() {
		System.out.println("这是一个宠物");
	}
}
java
public class Cat extends Pet{
	public void show() {
		super.show();
		System.out.println("这是一只猫");
	}
}

当调用子类对象的某个继承自父类的方法时,如果子类没有对该方法进行重写,则调用的是父类的方法,如果子类对该方法进行重写,则调用的是子类的重写方法。

重写需要注意的事项:

1.进行重写时,可以使用super.方法名的方式保留父类方法的业务逻辑。 2.构造方法不能被重写。

方法重写的规则:

1.方法名相同 2.参数列表相同 3.返回值类型相同或重写方法的返回值类型是父类原方法的返回值类型的子类 4.子类重写方法的访问权限不能小于父类方法的访问权限

public > protected > 默认 > private 当父类方法使用public修饰时,子类重写方法只能有public修饰 当父类方法使用protected修饰时,子类重写方法只能有public,protected修饰 当父类方法使用默认修饰时,子类重写方法只能有public,protected,默认修饰 当父类方法使用private修饰时,子类重写方法只能有public,protected,默认,private修饰

Object类是所有类的父类

Object类经常被其子类重写的方法 toString():输出对象信息

== 和 equals()的区别

1)

如果数据是基本数据类型的,==比较的是两个数据的值是否相等。 如果数据是引用类型的,==比较的是两个数据的内存地址是否相等。

2)

equals()是Object类中定义的一个方法,只用引用数据类型可以调用,基本数据类型无法调用,默认方法体是通过==进行判断的,比较两个对象的内存地址是否相等。

equals()经常会被Object的子类进行重写,比较典型的是String类中的重写,改为判断两个字符串的值是否相来决定最终的结果。

instanceof关键字

判断某个对象是否属于某个类 A instanceof B 判断A对象是否是通过B类来创建的,表达式的结果是boolean true表示A是通过B来创建的 如果A不是通过B来创建的,则表达式直接报错。