一. 概念:
继承就是使用extends关键字,是一个类 (子类) 可以继承另外一个类 (父类) ,继承的好处就是可以使用被继承类 (父类) 里的所有成员(也就是变量或者方法),说白了就是可以复用代码 (减少代码量,加快开发效率) ,此外继承也是java编程语言中多态里重写的前提。
二. 格式:
例如:
public class 子类 extends 父类{
}
1. 定义一个父类 类名为Fu
public class Fu{
String name;
int age;
public void run(){
System.out.println("跑路了。。。。。。");
}
}
2. 定义一个子类 类名为Zi 使用关键字extends 继承Fu类
// 继承关键字 extends Zi extends Fu
public class Zi extends Fu{
//此处省略代码,只做继承的演示
}
3. 定义一个测试类
public class Test {
public static void main(String[] args) {
// 创建子类实例化对象
Zi zi = new Zi();
// 使用的是父类里的属性
zi.name="张三";
zi.age=18;
// 调用的是父类里的方法
zi.run(); //跑路了。。。。。。
// 访问的是父类里的成员属性
System.out.println(zi.name); // 张三
System.out.println(zi.age); // 18
}
}
三. 抽取父类:
如下图所示:
四. 注意事项
1. 一个子类只能继承一个父类
如图所示:
代码如下:
1. 定义父类1
public class Fu1{
String name;
int age;
public void run(){
System.out.println("跑路了。。。。。。");
}
}
2. 定义父类2
public class Fu2{
String name;
int age;
public void run(){
System.out.println("跑路了。。。。。。");
}
}
3. 定义子类 同时继承以上两个父类,可以看到报错,如下图所示
2. 一个父类可以被多个子类继承
如图所示:
代码如下:
1. 定义父类
public class Fu{
String name;
int age;
public void run(){
System.out.println("跑路了。。。。。。");
}
}
2. 定义子类1
public class Zi1 extends Fu{
}
3. 定义子类2
public class Zi2 extends Fu{
}
4. 定义测试类
public class Test {
public static void main(String[] args) {
// 创建子类1实例化对象
Zi1 zi1 = new Zi1();
// 使用的是父类里的属性
zi1.name="张三";
zi1.age=18;
// 调用的是父类里的方法
zi1.run(); //跑路了。。。。。。
// 访问的是父类里的成员属性
System.out.println(zi1.name); // 张三
System.out.println(zi1.age); // 18
// 创建子类2实例化对象
Zi2 zi2 = new Zi2();
// 调用的是父类里的方法
zi2.run(); //跑路了。。。。。。
}
}
5. 执行结果如下图:
3. 祖孙三代 间接继承(多重继承)
如图所示:
代码如下:
1. 定义父类
public class Fu{
String name;
int age;
public void run(){
System.out.println("跑路了。。。。。。");
}
}
2. 定义子类
// 继承关键字 extends Zi extends Fu
public class Zi extends Fu{
}
3. 定义孙子类
public class SunZi extends Zi{
}
4. 定义测试类
public class Test {
public static void main(String[] args) {
// 创建子类1实例化对象
Zi zi = new Zi();
// 使用的是父类里的属性
zi.name="张三";
zi.age=18;
// 调用的是父类里的方法
zi.run(); //跑路了。。。。。。
// 访问的是父类里的成员属性
System.out.println(zi.name); // 张三
System.out.println(zi.age); // 18
// 创建子类2实例化对象
Zi2 zi2 = new Zi2();
// 调用的是父类里的方法
zi2.run(); //跑路了。。。。。。
// 创建孙子类实例化对象
SunZi sunZi = new SunZi();
// 调用的是父类里的方法
sunZi.run();
}
}
5. 执行结果如下图:
五. 继承访问父类里的属性或方法
1. 属性不重名
定义一个父类
public class Father{
int num=20;
}
定义一个子类并继承父类
public class Son extends Father{
int age=10;
public void show(){
//访问父类中的属性
System.out.println(num); // 20
//访问子类中的属性
System.out.println(age); // 10
}
}
定义测试类
public class Test {
public static void main(String[] args) {
Son son = new Son();
son.show();
}
}
结果如下图:
2. 属性重名
定义一个父类
public class Father{
int num=20;
}
定义一个子类并继承父类
public class Son extends Father{
int num=10;
public void show(){
//访问父类中的属性
System.out.println(num); // 10
//访问子类中的属性
System.out.println(num); // 10
}
}
定义测试类
public class Test {
public static void main(String[] args) {
Son son = new Son();
son.show();
}
}
结果如下图:
产生问题:
在子类和父类属性同名的情况下,无法区分子类和父类的属性,因此会通过就近原则优先访问子类中的属性,所以最后输出的结果都属子类中的属性值
解决办法:使用this 和 super关键字
this.访问自己的成员变量,super访问父类的成员变量
修改子类中的代码如下:
class Son extends Father{
int num=10;
public void show(){
// super访问父类中的属性
System.out.println(super.num);
// this访问当前类中的属性 也就是这里子类的属性
System.out.println(this.num);
}
}
结果如下图:
3. 方法不重名
父类中定义一个eat方法
public class Father {
int num = 20;
public void eat() {
System.out.println("fu吃。。。。。。。。。。。。。");
}
}
定义一个子类并继承父类
class Son extends Father{
int num=10;
public void show(){
// super访问父类中的属性
System.out.println(super.num);
// this访问当前类中的属性 也就是这里子类的属性
System.out.println(this.num);
}
}
定义测试类
public class Test {
public static void main(String[] args) {
Son son = new Son();
son.show();
son.eat();
}
}
结果如下图:
4. 方法重名
定义一个父类
public class Father {
int num = 20;
public void eat() {
System.out.println("fu吃。。。。。。。。。。。。。");
}
}
定义一个子类并继承父类
public class Son extends Father {
int num=10;
public void show(){
// super访问父类中的属性
System.out.println(super.num);
// this访问当前类中的属性 也就是这里子类的属性
System.out.println(this.num);
}
public void eat() {
System.out.println("zi吃。。。。。。。。。。。。。");
}
}
定义测试类
public class Test {
public static void main(String[] args) {
Son son = new Son();
son.show();
son.eat();
}
}
结果如下图:
产生问题:
在子类和父类方法同名的情况下,无法区分子类和父类的方法,因此会通过就近原则优先访问子类中的方法,所以最后输出的是子类方法中的执行结果
解决办法:使用this 和 super关键字
this.访问自己的成员方法,super访问父类的成员方法
修改子类中的代码如下:
public class Son extends Father {
int num = 10;
public void show() {
// super访问父类中的属性
System.out.println(super.num);
// this访问当前类中的属性 也就是这里子类的属性
System.out.println(this.num);
super.eat();
this.eat();
}
public void eat() {
System.out.println("zi吃。。。。。。。。。。。。。");
}
}
修改测试类中的代码如下:
public class Test {
public static void main(String[] args) {
Son son = new Son();
son.show();
//son.eat();
}
}
结果如下图: