1.继承
1.1 继承概述
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法
继承的格式:
- 格式:public class 子类名 extends 父类名()
- 范例:public class Zi extends Fu()
- Fu:是父类,也被称为基类和超类
- Zi:是子类,也被称为派生类
继承子类的特点:
- 子类可以有父类的内容
- 子类还可以有自己特有的内容(儿子可以继承爸爸的方法)
package com.szy001;
//父类
public class Fu {
public void show(){
System.out.println("show方法被调用");
}
}
package com.szy001;
//子类
public class Zi extends Fu{
public void method(){
System.out.println("method方法被调用");
}
}
package com.szy001;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Fu f=new Fu();
f.show();
Zi z=new Zi();
z.method();
z.show();
}
}
1.2继承的好处和弊端
继承的好处:
- 提高了代码的复用性(多个类相同的成员可以放到一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
继承的弊端:
- 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性。
什么时候使用继承?
- 继承体现的关系:is a
- 假设法:我有两个类A和B,如果他们满足A是B的一种,或者B是A的一种,就说明他们之间存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承。
- 举例:苹果和水果,猫和动物
1.3继承中变量的访问特点
在子类方法中访问一个变量
- 先子类局部范围找
- 再子类成员范围找
- 然后父类成员范围找
- 最后如果都没有就报错(不考虑父亲的父亲……)
package com.szy002;
public class Fu1 {
public int age=44;
}
package com.szy002;
public class Zi1 extends Fu1{
public int age=22;
public int height=178;
public void show(){
age=79;
System.out.println(height);
System.out.println(age);
}
}
package com.szy002;
public class Demo1 {
public static void main(String[] args) {
Zi1 z=new Zi1();
z.show();
}
}
1.4 super
super关键字的用法和this关键字的用法相似
- this:代表本类对象的引用
- super:代表父类存储空间的标识(可以理解为父类对象的引用)
1.5继承中构造方法的访问特点
子类中所有的构造方法默认都会访问父类中无参的构造方法
为什么呢?
- 因为子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化之前,一定要先完成父类数据的初始化
- 每一个子类构造方法的第一条语句默认都是:super()
如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
-
通过使用super关键字去显示的调用父类的带参构造方法
-
在父类中自己提供一个无参构造方法
-
推荐:自己给出无参构造方法
1.6继承中成员方法的访问特点
通过子类对象访问一个方法
- 先在子类成员范围找
- 再在父亲成员范围找
- 如果都没有就报错(不考虑父亲的父亲……)
1.7 super内存图
1.8方法重写
方法重写概述
- 子类中出现了和父类一模一样的方法声明
方法重写的应用
-
当子类需要父类的功能,而功能主体子类有自己特有的内容时,可以重写父类中的方法,这样即沿袭了父类的功能,又定义了子类特有的内容
-
练习:手机类和新手机类
package com.szy003; /* 手机类 */ public class Phone { public void call(String name){ System.out.println("给"+name+"打电话"); } }
package com.szy003; /* 新手机类 */ public class NewPhone extends Phone { /* public void call(String name){ System.out.println("开启视频功能"); super.call(name); } */ @Override//注解方法重写,用于检查方法重写的正确性 public void call(String name){//方法重写时要跟原来用一样的方法名 System.out.println("开启视频功能"); super.call(name); } }
package com.szy003; /* 手机测试类 */ public class PhoneDemo { public static void main(String[] args) { //创建对象,调用方法 Phone p=new Phone(); p.call("杨小寒"); NewPhone np=new NewPhone(); np.call("小白狗"); } }
@Override
- 是一个注解(注解后面会学习到)
- 可以帮助我们检查重写方法的方法声明的正确性
1.9方法重写注意事项
- 私有方法不能被重写(父类私有成员子类是不能继承的)
- 子类方法访问权限不能更低(public>默认>私有)
1.10 Java中继承的注意事项
- Java中类只支持单继承,不支持多继承(一个孩子只能有一个爸爸,不能有两个)
- Java中类支持多层继承(儿子继承爸爸的,爸爸继承爷爷的)
案例:老师和学生
需求:定义老师类和学生类,然后写代码测试,最后找到老师类和学生类当中的共性内容,抽取出一个父类,用继承的方式改写代码,并进行测试。
-
用学生类和老师类的方法:
package com.szy004; /* 老师类 */ public class Teacher { private String name; private int age; public Teacher() { } public Teacher(String name, int age) { this.name = name; this.age = age; } 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; } public void teach(){ System.out.println("教书育人"); } }
package com.szy004; /* 学生类 */ public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } 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; } public void study(){ System.out.println("好好学习天天向上!"); } }
package com.szy004; /* 测试类 */ public class Demo { public static void main(String[] args) { //创建老师类对象进行测试 Teacher t1=new Teacher(); t1.setName("喜羊羊"); t1.setAge(7); System.out.println(t1.getName()+","+t1.getAge()); t1.teach(); Teacher t2=new Teacher(); t2.setName("灰太狼"); t2.setAge(33); System.out.println(t2.getName()+","+t2.getAge()); t2.teach(); } }
测试结果:
-
用继承的方法
package com.szy005; /* 人类 */ public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } 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; } }
package com.szy005; public class Teacher extends Person{ public Teacher(){//无参构造方法 } public Teacher(String name,int age){//带参构造方法 super(name,age); } public void teach(){ System.out.println("用爱成就每一位学生"); } }
package com.szy005; public class Student extends Person{ public Student(){//无参构造方法 } public Student(String name,int age){//带参构造方法 super(name,age); } public void study(){ System.out.println("好好学习天天向上!"); } }
package com.szy005; /* 测试类 */ public class TestDemo { public static void main(String[] args) { //创建老师对象并测试方法 Teacher t1=new Teacher(); t1.setName("李老师"); t1.setAge(77); System.out.println(t1.getName()+","+t1.getAge()); t1.teach(); Teacher t2=new Teacher("刘老师",42); System.out.println(t2.getName()+","+t2.getAge()); t2.teach(); //创建学生对象并测试方法 Student s1=new Student(); s1.setName("小红"); s1.setAge(7); System.out.println(s1.getName()+","+s1.getAge()); s1.study(); Student s2=new Student("小华",13); System.out.println(s2.getName()+","+s2.getAge()); s2.study(); } }
测试结果:
案例:猫和狗
需求:请采用继承的思想实现猫和狗的案例,并在测试类中进行测试。
package com.szy006;
/*
动物类
*/
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
}
package com.szy006;
/*
猫类
*/
public class Cat extends Animal {
public Cat(){
//无参构造方法
}
public Cat(String name,int age){//带参构造方法
super(name,age);
}
public void catchMouse(){
//抓老鼠方法
System.out.println("抓老鼠一千只");
}
}
package com.szy006;
/*
狗类
*/
public class Dog extends Animal{
public Dog(){
//无参构造方法
}
public Dog(String name,int age){//带参构造方法
super(name,age);
}
public void watchDoor(){
//看门方法
System.out.println("为主人看门");
}
}
package com.szy006;
/*
测试类
*/
public class AnimalDemo {
public static void main(String[] args) {
//创建猫类对象并进行测试
Cat c1=new Cat();
c1.setName("咪咪");
c1.setAge(3);
System.out.println(c1.getName()+":"+c1.getAge());
c1.catchMouse();
Cat c2=new Cat("飘飘",2);
System.out.println(c2.getName()+":"+c2.getAge());
c2.catchMouse();
//创建狗类对象并进行测试
Dog d1=new Dog();
d1.setName("二哈");
d1.setAge(3);
System.out.println(d1.getName()+":"+d1.getAge());
d1.watchDoor();
Dog d2=new Dog("小哈",1);
System.out.println(d2.getName()+":"+d2.getAge());
d2.watchDoor();
}
}