1.1继承概述
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
格式:public class 子类名 extends 父类名{}
父类又称基类/超类;子类又称派生类。
继承中子类的特点:子类可以有父类的内容,还可以有自己特有的内容。
Fu.java
package lwj_01;
/*
父类
*/
public class Fu {
public void show(){
System.out.println("show方法被调用");
}
}
Zi.java
package lwj_01;
/*
子类
*/
public class Zi extends Fu{
public void method() {
System.out.println("method方法被调用");
}
}
Demo.java
package lwj_01;
/*
测试类
*/
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继承的好处和弊端
好处:
提高了代码的复用性(多个类相同的成员可以放到同一个类中)
提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
弊端:
继承让类与类之间产生了关系,类的耦合性增加了,当父类发生变化时,子类实现也不得不跟着变化,削弱了子类的独立性。
什么时候使用继承?
继承体现的关系:什么是什么的一种。假设法:有A、B两类,若满足A是B的一种,或B是A的一种,说明存在继承关系,可以使用继承。举例:①苹果和水果 √ ②猫和动物 √ ③猫和狗 ×
1.3继承中变量的访问特点
在子类方法中访问一个变量:①先子类局部范围找 ②再子类成员范围找 ③最后父类成员范围找 (如果都没有就报错,不考虑父类的父类)
Fu.java
package lwj_01;
/*
父类
*/
public class Fu {
public int age=40;
}
Zi.java
package lwj_01;
/*
子类
*/
public class Zi extends Fu{
public int height=175;
public int age=20;
public void show(){
int age=30;
System.out.println(age);//30
System.out.println(height);//175
//System.out.println(weight);erro——weight找不到就报错
}
}
Demo.java
package lwj_01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z=new Zi();
z.show();
}
}
1.4 super关键字
this:代表本类对象的引用(this指向调用该方法的对象,一般在当前类中使用this关键字,所以常说this代表本类对象的引用。)
super:代表父类存储空间的标识(可理解为父类对象引用)
关键字 | 访问成员变量 | 访问构造方法 | 访问成员方法 |
this | this.成员变量 访问本类成员变量 |
this(...) 访问本类构造方法 |
this.成员方法(...) 访问本类成员方法 |
super | super.成员变量 访问父类成员方法 |
super(...) 访问父类构造方法 |
super.成员方法(...) 访问父类成员方法 |
Fu.java
package lwj_01;
/*
父类
*/
public class Fu {
public int age=40;
}
Zi.java
package lwj_01;
/*
子类
*/
public class Zi extends Fu{
public int age=20;
public void show(){
int age=30;
System.out.println(age);//30
//访问本类成员变量age;
System.out.println(this.age);//20
//访问父类成员变量age;
System.out.println(super.age);//40
}
}
Demo.java
package lwj_01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z=new Zi();
z.show();
}
}
1.5继承中构造方法的访问特点
子类中所有的构造方法,默认都会访问父类中无参构造方法。为什么?
①因为子类会继承父类中的数据,可能还会使用父类的数据,所以子类初始化之前,一定要先完成父类数据的初始化。(所有子类构造方法创建对象之前都会去访问父类构造方法就是父类数据的初始化。)
②每一个子类构造方法的第一条语句默认都是super()。
如果父类中没有无参构造方法,只有带参构造方法,该怎么办?
①通过使用super关键字去显示的调用父类的带参构造方法。
②在父类中自己提供一个无参构造方法。(推荐方法)
package lwj_01;
/*
父类
*/
public class Fu {
/*public Fu(){
System.out.println("Fu中无参构造方法被调用");
}*/
public Fu(){}//在父类中自己提供一个无参构造方法。(推荐方法)
public Fu(int age){
System.out.println("Fu中带参构造方法被调用");
}
}
package lwj_01;
/*
子类
*/
public class Zi extends Fu{
public Zi(){
//super();默认访问无参构造方法,写与不写super()都一样。
//super(20);通过使用super关键字去显示的调用父类的带参构造方法。
System.out.println("Zi中无参构造方法被调用");
}
public Zi(int age){
//super();默认访问无参构造方法,写与不写super()都一样。
//super(20);通过使用super关键字去显示的调用父类的带参构造方法。
System.out.println("Zi中带参构造方法被调用");
}
}
package lwj_01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象
Zi z=new Zi();
Zi Z2=new Zi(20);
}
}
1.6继承中成员方法的访问特点
通过子类对象访问一个方法:①先子类成员范围找 ②再父类成员范围找(如果都没有就报错,不考虑父类的父类......)
package lwj_01;
/*
父类
*/
public class Fu {
public void show(){
System.out.println("Fu中show()方法被调用");
}
}
package lwj_01;
/*
子类
*/
public class Zi extends Fu{
public void method(){
System.out.println("Zi中method()方法被调用");
}
public void show(){
super.show();//通过super关键字访问父类show()方法
System.out.println("Zi中show()方法被调用");
}
}
package lwj_01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z=new Zi();
z.method();
z.show();
//z.test();erro——找不到test报错
}
}
1.7方法重写
概述:子类出现了和父类中一模一样的方法声明。
应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样既沿袭了父类的功能,又定义了子类特有的内容。
@Overrider:是一个注解,帮助我们检查重写方法的方法声明的正确性。
package lwj_06;
public class Phone {
/*
手机类
*/
public void call(String name){
System.out.println("给"+name+"打电话");
}
}
package lwj_06;
/*
新手机类
*/
public class NewPhone extends Phone {
public void call(String name){
System.out.println("开启视频功能");
// System.out.println("给"+name+"打电话");
super.call(name);
}
}
package lwj_06;
/*
测试类
*/
public class PhoneDemo {
public static void main(String[] args) {
//创建对象,调用方法
Phone p=new Phone();
p.call("魏晨");
System.out.println("--------------");
NewPhone np=new NewPhone();
np.call("魏晨");
}
}
1.8方法重写注意事项
①私有方法不能被重写(父类私有成员,子类是不能继承的)
②子类方法访问权限不能更低(public>默认>私有)
package lwj_07;
public class Fu {
private void show(){
System.out.println("Fu中show()方法被调用");
}
//私有方法不能被重写(父类私有成员子类是不能被继承的)
/*
public void method(){
System.out.println("Fu中method()方法被调用");
}
//子类方法访问权限不能更低(public>默认>私有)
*/
void method(){
System.out.println("Fu中method()方法被调用");
}
}
package lwj_07;
public class Zi extends Fu{
/*
@Override
private void show(){
System.out.println("Zi中show()方法被调用");
}
//私有方法不能被重写(父类私有成员子类是不能被继承的)
*/
/*
@Override
void method(){
System.out.println("Zi中method()方法被调用");
}
//子类方法访问权限不能更低(public>默认>私有)
*/
@Override
public void method(){
System.out.println("Zi中method()方法被调用");
}
}
1.9Java中继承的注意事项
①Java中类只支持单继承,不支持多继承。
②Java中类支持多层继承。
举例:有Son类 、Mother类 、Father类 、Granddad类
(一)public class Son extends Father,Mother{} //不可以这样写,Java中类只支持单继承,不支持多继承。
(二)public class Granddad{}
public class Father extends Granddad{}
public class Son extends Father{}
//可以这样写,Java中类支持多层继承。