类可以有两种重要的成员:成员变量和方法。子类的成员中有一部分是子类自己声明、定义的,另一部分是从它的父类继承的。那么,
什么叫继承呢?所谓子类继承父类的成员变量作为自己的一个成员变量,就好像它们是在子类中直接声明一样,可以被子类中自己定义的任何实例方法操作,也就是说,一个子类继承的成员应当是这个类的完全意义的成员,如果子类中定义的实例方法不能操作父类的某个成员变量,该成员变量就没有被子类继承;所谓子类继承父类的方法作为子类中的一个方法,就像它们是在子类中直接定义了一样,可以被子类中自己定义的任何实例方法调用。
使用继承
编写父类
[访问修饰符] class Pet { //公共的属性和方法 }
编写子类,继承父类
[访问修饰符] class Dog extends Pet { //子类特有的属性和方法 }
继承是Java中实现代码重用的重要手段之一。Java中只支持单根继承,即一个类只能有一个直接父类
案例:
package cn.bdqn.demo04;
public class Pet {
private String name;
private int health;
private int love;
// 添加构造方法
public Pet() {
}
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public void print() {
System.out.println("宠物信息:昵称:" + this.getName() + ",健康值:"
+ this.getHealth() + ",亲密度:" + this.getLove());
}
}
package cn.bdqn.demo04;
public class Cat extends Pet {
// 定义Cat类独有的属性
private String color;
public Cat() {
super();// 调用父类Pet类里的无参构造方法
}
public Cat(String name, int health, int love, String color) {
super(name, health, love);
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
package cn.bdqn.demo04;
public class Dog extends Pet {
//strain属性是DOg类里独有的属性,其它类没有,所以要在Dog类里定义
private String strain;
public Dog() {
}
public Dog(String name, int health, int love, String strain) {
super(name, health, love);
this.strain = strain;
}
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
}
package cn.bdqn.demo04;
public class Penguin extends Pet {
// 定义Penguin类里独有的属性
private String sex;
public Penguin() {
super();// super表示父类Pet对象,所以这个地方表示调用父类的无参构造方法
}
public Penguin(String name, int health, int love, String sex) {
super(name, health, love);// 表示调用父类Pet类的有参构造方法
this.sex = sex;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package cn.bdqn.demo04;
public class Test {
public static void main(String[] args) {
// 创建Dog类对象
Dog dog1 = new Dog("旺财", 99, 99, "金毛");
//在Dog类中没有setName()方法,但是DOg类对象dog1是可以调用,因为Dog类继承了Pet类,所以dog1可以调用父类Pet类里的setName()方法
dog1.setName("来福");
dog1.print();
//创建Penguin类对象
Penguin penguin1 = new Penguin("QQ", 98, 100, "公");
penguin1.setHealth(100);
penguin1.print();
//创建Cat类对象
Cat cat1 = new Cat("Tom", 100, 80, "蓝色");
cat1.print();
//hashCode()在Cat里没有、在Cat的父类Pet类里也没有,hashCode()方法存在于Object类中,Object类是Pet类的默认父类,所以Cat类对象可以使用Pet类里的方法,也可以使用Pet类的父类里的方法
//声明一个类,如果没有指定其父类是谁,系统会让此类默认去继承Object类
int num =cat1.hashCode();
System.out.println(num);//1694203642
}
}
super
子类访问父类成员
访问父类构造方法
super(); super(name);
访问父类属性
super.name;
访问父类方法
super.print();
super关键字:
(1)使用super关键字,super代表父类对象
(2)在子类构造方法中调用且必须是第一句
(3)不可以访问父类中定义为private的属性和方法
super关键字来访问父类的成员
super只能出现在子类的方法和构造方法中
super调用构造方法时,只能是第一句
super不能访问父类的private成员
继承条件下构造方法的调用规则
子类构造方法没有通过super显式调用父类的有参构造方法,也没通过this显式调用自身其他构造方法
系统默认调用父类的无参构造方法
子类构造方法通过super显式调用父类的有参构造方法
执行父类相应构造方法,而不执行父类无参构造方法
子类构造方法通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则
子类继承父类的什么?
继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里
继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里
案例:
package cn.bdqn.demo05;
public class Father {
private String name;
private int age;
public double height;
public Father() {
super();//调用Father类的父类Object类的无参构造方法
System.out.println("我是Father类里的无参构造方法");
}
public Father(String name, int age,double height) {
super();//调用Father类的父类Object类的无参构造方法
this.name = name;
this.age = age;
this.height = height;
System.out.println("我是Father类里的有参构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void test(){
System.out.println("我是Father类里的私有test()方法");
}
public void print(){
System.out.println("我是Father类里的公共print()方法");
}
}
package cn.bdqn.demo05;
public class Son extends Father {
private double money;
public Son() {
super();//调用的Son类的父类Father类里的无参构造方法
System.out.println("我是Son类里的无参构造方法");
}
public Son(String name, int age, double height, double money) {
super(name, age, height);//调用Son类的父类Father类里的有参构造方法
this.money = money;
System.out.println("我是Son类里的有参构造方法");
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void printInfo(){
//输出父类里的属性
//super不能直接调用父类里被private修饰的属性
// System.out.println(super.name);
// System.out.println(super.age);
System.out.println(super.height);
//super不能直接调用父类里被private修饰的方法
// super.test();
super.print();
}
}
package cn.bdqn.demo05;
public class Test {
public static void main(String[] args) {
// 使用Son类的无参构造方法创建对象
Son son1 = new Son();
//创建Son类对象一共调用了几次构造方法??? 3次
System.out.println("----------------");
Son son2 = new Son("张三", 22, 173, 999);
son2.printInfo();
}
}
不能被继承的父类成员
private成员
子类与父类不在同包, 使用默认访问权限的成员
构造方法
何时使用继承?
继承与真实世界类似
只要说“猫是哺乳动物”,猫的很多属性、行为就 不言自明了
藏獒是一种狗
符合is-a关系的设计使用继承
继承是代码重用的一种方式
将子类共有的属性和行为放到父类中