继承
一、什么是继承
继承是是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
二、继承概述
继承的格式
1. 格式:public class 子类名 extends 父类名
2. 范例:public class Zi extends Fu( )
3. Fu:是父类,也被称为基类、超类
4. Zi:是子类, 也被称为派生类
三、继承代码演示
下面展示一些 父类代码
。
package Dome;
public class Fu {
public void show(){
System.out.println("Fu类show方法被调用!!!");
}
}
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
public void method(){
System.out.println("Zi中method方法被调用");
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi();
z.method();
z.show();
}
}
可见,Zi继承了Fu的方法,因此,在Zi中可以直接调用Fu中的show方法。
四、继承的好处和弊端
- 继承的好处
1)提高了代码的复用性(多个类相同的成员可以放到同一个类中)
2)提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
- 继承弊端
继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着发生变化,削弱了子类的独立性
五、什么时候使用继承
- 继承体现的关系:is a
- 假设法:我有两个类A和B,如果他们满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这时候就可以考虑使用继承关系来体现,否则就不能滥用继承关系
- 举例:苹果与水果 、 猫和狗
六、继承中变量的访问特点
下面展示一些 父类代码
。
package Dome;
public class Fu {
int age = 40;
}
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
int age = 20;
public void method(){
System.out.println(age);
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi();
z.method();
}
}
子类和父类都有age,如果代码执行,调用的age是子类的还是父类的呢?那就让我们实践见真理
那么如果方法中也有age呢?会发生什么?
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
int age = 20;
public void method(){
int age = 10;
System.out.println(age);
}
}
通过这个案例我们可以得出以下结论(就近原则)
在子类方法中访问一个变量
- 子类局部范围找
- 子类成员范围找
- 父类成员范围找
- 如果没有就报错(不考虑父亲的父亲)
七、super
那么如果我想要访问父类的变量怎么办呢???
这时候我们引入super关键字
super关键字的用法和this关键字的用法相似
- this:代表本类对象的引用
- super:代表父类存储空间的标识(可以理解为父类对象引用)
关键字 | 访问成员变量 | 访问构造方法 | 访问成员方法 |
---|---|---|---|
this | this.成员变量 访问本类成员变量 | this(…)访问本类构造方法 | this.成员方法() 访问本类成员方法 |
super | super.成员变量 访问父类成员变量 | super(…) 访问父类构造方法 | super.成员方法(…) 访问父类成员方法 |
下面展示一些 父类代码
。
package Dome;
public class Fu {
int age = 40;
}
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
int age = 20;
public void method(){
int age = 10;
System.out.println(age);
System.out.println(this.age);
System.out.println(super.age);
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi();
z.method();
}
}
通过this和super我们就可以调用不同的同名变量或者方法
八、继承中构造方法的访问特点(1)
引入案例
下面展示一些 父类代码
。
package Dome;
public class Fu {
public Fu() {
System.out.println("Fu无参构造方法被调用");
}
public Fu(int age){
System.out.println("Fu有参构造方法被调用");
}
}
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
public Zi() {
System.out.println("Zi无参构造方法被调用");
}
public Zi(int age){
System.out.println("Zi有参构造方法被调用");
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi();
}
}
当执行程序的时候发现
这是为什么呢??
那么让我们尝试用有参构造方法试一试
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi(10);
}
}
为什么子类所有构造方法默认都会访问父类无参的构造方法呢???
- 因为子类会默认继承父类中的数据, 还可能会使用父类的数据。所以,子类初始化之前,一定会完成父类数据初始化。
- 每一个子类构造方法的第一条默认语句是super()
那么倘若Fu类中没有无参构造方法,只有有参构造方法,程序应该怎么该呢??
下面展示一些 父类代码
。
package Dome;
public class Fu {
/*public Fu() {
System.out.println("Fu无参构造方法被调用");
}*/
public Fu(int age){
System.out.println("Fu有参构造方法被调用");
}
}
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
public Zi() {
super(20);
System.out.println("Zi无参构造方法被调用");
}
public Zi(int age){
super(20);
System.out.println("Zi有参构造方法被调用");
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi();
}
}
只需要在子类构造方法加super(参数)即可
温馨提示:如果一个对象中自己写了一个有参构造方法,那么默认的无参构造方法将会消失,因此需要自己手动添加无参构造方法
九、继承中构造方法的访问特点(2)
如果子和父中有同样的方法,那会出现怎么样的情况呢
下面展示一些 父类代码
。
package Dome;
public class Fu {
public void show(){
System.out.println("Fu中show被调用");
}
}
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
public void show(){
System.out.println("Zi中show被调用");
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
Zi中的show方法被调用,而Fu中的show方法没有被调用
如果Zi中没有show方法,那么就会调用Fu中的show方法
如果想要既调用Zi的show方法又调用Fu的show方法该怎么办呢???
下面展示一些 子类代码
。
package Dome;
public class Zi extends Fu {
public void show(){
super.show();//调用Fu中的show方法
System.out.println("Zi中show被调用");
}
}
这样就可以了!!!!
总结
通过子类对象访问一个方法
- 子类成员范围找
- 父类成员范围找
- 如果没有就报错(不考虑父亲的父亲)
十、方法重写
方法重写的概述
- 子类中出现和父类一模一样的声明
方法重写的应用
- 当子类需要父类功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的功能
下面展示一些 父类代码
。
package Dome;
public class Phone {
public void call(){
System.out.println("打电话!!");
}
}
下面展示一些 子类代码
。
package Dome;
public class NewPhone extends Phone{
/*
call方法重写
*/
@Override //注解 可以检验方法重写时候方法声明的正确性
public void call(){
System.out.println("视频!");
super.call(); ///调用Fu中的call方法
}
}
下面展示一些 测试类代码
。
package Dome;
/*
测试类
*/
public class ExtendDome {
public static void main(String[] args) {
Phone p = new Phone();
p.call();
System.out.println("-------------------");
NewPhone np = new NewPhone();
np.call();
}
}
十一、方法重写注意事项
- 私有方法不能被重写(父亲私有成员子类是不能继承的,也就是private)
- 子类方法访问权限不能更低(public > 默认(不写就是默认) > 私有(private))
十二、继承注意事项
- Java中类只支持单继承, 不支持多继承
- Java中类支持多层继承
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/95049.html