1.继承的概述
泛指把前人的作风、文化、知识、财产等接受过来
java中的继承
让类与类之间产生父子关系
被继承的类叫做父类(基类、超类)
继承的类叫做子类(派生类)
格式(extends)
class 父类{
//.....
}
class 子类 extends 父类{
//.....
}
子类继承父类之后有什么效果
子类可以使用父类中的非私有成员(成员变量、成员方法)
例子:
//定义父类Parent
public class Parent {
//成员变量
private Stringname;
private int age;
//公共访问方式
//快捷键: alt + insert 快速创建 getXXX(), setXXX()和构造方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
//构造方法
//无参构造
public Parent() {
}
//全参构造
public Parent(String name,int age) {
this.name = name;
this.age = age;
}
}
//定义一个子类 Child 继承 父类Parent
public class Childextends Parent {
}
//测试类
public class Test {
//main函数是程序的主入口,所有的代码都是从这里开始
public static void main(String[] args) {
//1.创建一个子类对象
Child child =new Child();
//2.给对象的成员变量赋值
child.setName("张三");
child.setAge(12);
//3.打印对象成员变量
System.out.println("姓名:"+child.getName()+"年龄:"+child.getAge());
/*
子类可以使用父类中的非私有成员(成员变量、成员方法)*/
}
}
运行结果:
2.继承的使用场景
·多个类中存再相同的属性和行为时,可以将这些内容提取出来放到一个新类中,让这些类和新类产生父子关系,实现代码复用
例子:定义继承关系的动物类并使用
需求:分别定义Dog类,Pig类,它们共有属性:name、age、sex,共有的行为有:eat(),两者特别的行为时:watch(),snore()
//定义一个父类 Animal 动物类
public class Animal {
//成员变量
//姓名
private Stringname;
//年龄
private int age;
//性别
private Stringsex;
//成员方法
//吃饭行为
public void eat(){
System.out.println(this.name+"正在吃饭....");
}
//公共访问方法
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
//构造方法
//无参构造
public Animal() {
}
//全参构造
public Animal(String name,int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
//定义一个子类 Dog 继承父类Animal
public class Dogextends Animal{
//成员方法
public void watch(){
System.out.println(this.getName()+"正在看家");
}
}
//定义一个子类 Pig 继承父类 Animal
public class Pigextends Animal {
//成员方法
public void snore(){
System.out.println(this.getName()+"正在打鼾");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//1.创建一个Dog类的对象
Dog dog =new Dog();
//2.给dog对象成员对象赋值
dog.setName("哈士奇");
//3.打印dog对象的成员变量
System.out.println("姓名:"+dog.getName());
//4.调用dog对象的方法
dog.eat();
dog.watch();
System.out.println("============");
//1.创建一个pig类的对象
Pig pig =new Pig();
//2.给pig对象成员变量赋值
pig.setName("荷兰猪");
//3.打印pig对象的成员变量
System.out.println("姓名:"+pig.getName());
//调用pig对象的成员方法
pig.eat();
pig.snore();
}
}
运行结果:
3.继承的优缺点
优点:
1.功能复用
直接将已有的属性和行为继承过来,实现了功能的复用,节省了大量的工作
2.便于拓展新功能
在已有的功能的基础上,更容易建立,扩充新功能
3.结构清晰,简化认识
同属性一个继承体系的相关类,他们直接结构层次清晰,简化了人们对代码结构的认识
4.易于维护
不同类之间的继承关系,让这些事物之间保持一定程度的一致性,大大降低了维护成本
缺点:
1.打破了封装性
父类向子类暴露了实现细节,打破了父类对象的封装性
2.高耦合性
类与类之间紧密的结合在一起,相互依赖性高
程序设计的追求
低耦合,高内聚
-耦合:两个(或更多)模块相互依赖于对方
-内聚:模块内部结构紧密,独立性强
4.继承关系中类成员的使用
1.继承关系中父类成员变量的使用
this和super的区别
this
-本质:对象
-用法:从本类开始找
super
-本质:父类内存空间的标识
-用法:从父类开始找
例子
需求:子父类中定义了同名的成员变量,如果使用?
分析:
A:子类中定义成员变量 int price ,默认值为10
B:父类中定义成员变量int price ,默认值为20
C:子类成员方法中定义局部变量int price ,默认值为 5
D:在子类成员方法中分别输出三个price的值
//定义父类 Fruit 水果类
public class Fruit {
//成员变量
//价格
int price =20;
}
//定义一个子类 Apple 苹果类
public class Appleextends Fruit{
//成员变量
//价格
private int price =10;
//成员方法
public void showPrice(){
int price =5;
System.out.println(price);//局部变量price 5
System.out.println(this.price);//子类成员变量price 10
System.out.println(super.price);//父类成员变量price 20
}
}
//测试类
public class Test {
public static void main(String[] args) {
//测试继承关系中,子父类之间成员变量的使用
//1.创建一个子类对象 苹果类对象
Apple apple =new Apple();
//2.调用对象方法
apple.showPrice();
/*
java中使用变量的规则,遵循就近原则
局部位置有就使用,没有就去本类的成员位置找
有就使用,没有就去父类的成员位置找
有就使用,没有就报错*/
}
}
运行结果:
2.继承关系中子父类成员方法的使用
例子
需求:子父类中定义了同名的成员方法,如何使用
定义武功类Martial:
练习内功:internalStrength()
练习招式:stroke()
定义九阴真经类NineYin:
练习内功:internalStrength()
练习招式:stroke()
九阴真经的修炼,不仅要练习基本内功还需要以柔克刚,需要扩展父类中的方法
简单的招式已经不足以未用,必须有九阴白骨爪这样的大招才可以使用,需要重新实现父类中的方法
//定义一个父类 Martial 武功类
public class Martial {
//成员方法
//练习内功
public void internalStrength(){
System.out.println("练习内功");
}
//练习招式
public void stroke(){
System.out.println("练习招式");
}
}
//定义一个子类 NineYin 九阴真经类 继承父类 Martial 武功类
public class NineYinextends Martial{
//成员方法
//练习内功
public void internalStrength(){
//调用父类中的成员方法
super.internalStrength();
System.out.println("练习以柔克刚");
}
public void stroke(){
System.out.println("练习九阴白骨爪");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//需求:调用NineYin中的方法
NineYin nineYin =new NineYin();
nineYin.internalStrength();
nineYin.stroke();
}
}
运行结果:
结论:
1.查找方法的原则:
就近原则
2.查找方法的顺序
本类->父类->更高的父类....Object
3.访问父类方法的方式
super.父类方法名()
4.定义重名方法的前提
父类功能不能万确满足实现需求,扩展父类功能
父类功能已过时,重新实现父类方法
3.继承关系中子父类构造方法的使用
需求:创建对象时,构造方法时如何被调用的?
分析:
A:定义父类Person,在默认无参构造中输出语句
B:定义子类Worker,继承Person,在默认无参构造中输出语句
C:定义测试类,创建子类Worker对象
结论:
·创建子类对象时,优先调用父类构造方法
·子类构造方法的第一行,隐含语句super(),用于调用父类的默认无参构造
需求:父类不存在默认的无参构造方法怎么办?
分析:子类创建对象时,必须先初始化该对象父类内容,若父类中不存在默认无参构造,必须手动调用父类其他构造
//定义一个父类Person
public class Person {
//构造方法
//无参构造
public Person(String name){
//System.out.println("Person类的无参构造");
System.out.println("Person类的带参构造");
}
}
//定义一个子类Worker
public class Workerextends Person {
//构造方法
//无参构造
public Worker(){
//super();//默认调用父类的无参构造
//System.out.println("Worker类的无参构造");
super("张三");
System.out.println("Worker类的带参构造");
}
}
/*
子类的构造方法中都会有一个默认的surper();用来访问父类的无参构造方法
如果父类没有无参构造,可以通过surper(参数)用来访问父类的带参构造*/
public class Test {
public static void main(String[] args) {
//创建一个子类Worker类的对象
Worker worker =new Worker();
}
}
运行结果:
5.方法的重写(Override)
·定义:
子类中出现和父类定义相同的方法的现象
·解释:
方法重写也叫方法复写,覆盖
方法名,参数列表,返回值类型都要相同
·注意事项:
父类私有方法无法重写
子类方法访问权限不能小于父类方法
子类不能比父类方法抛出更大的异常
使用场景:
扩展父类功能
父类功能过时,重新实现父类功能
四大权限修饰符修饰范围,从小到大分别是:
private,默认(什么都不写就是默认),protected,public
1.Java中的访问权限修饰符
prvate 本类
默认 本类、本包下的类中
protected 本类、本包下的类中、不同包下的子类中
public 本类、本包下的类中、不同包下的子类中、其他类中
总结
private:强调的是给自己使用
默认:强调的是给通报下的类使用
protected:强调的是给子类使用
public:强调的是给大家使用
2.方法重写和方法重载的区别
重载
方法名:相同
参数列表:不同(个数或对应位置类型)
返回值:无关
定义位置:同一个类
重写
方法名:相同
参数列表:相同
返回值类型:相同
修饰符:访问权限不小于被重写的方法
定义位置:子父类中
6.java中继承的特点
·单继承
Java只支持类的单继承,但是支持多层(重)继承
Java支持接口的多继承,语法为:
接口A extends 接口B,接口C,接口D....
·私有成员不能继承
只能继承父类中的非私有成员(成员变量,成员方法)
·构造方法不能被继承
构造方法用于初始化本类对象
创建子类对象时,需要调用父类构造方法初始化
该对象父类内容,若父类构造可以被继承
该操作会造成调用混乱
·继承体系了“is a”的关系
子类符合“is a”父类的情况,才能使用继承,其他情况不建议使用