Java学习笔记:面向对象技术(5)——继承

参考视频:bilibili遇见狂神说

2、继承

①、基本概念

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
  • extends的意思是“扩展”,子类是父类的扩展。
  • Java中类只有单继承,没有多继承。一个儿子只能有一个爸爸,但一个爸爸可以有多个儿子。
package 面向对象OOP.继承;

//人类
public class Person {
}
package 面向对象OOP.继承;

//老师是人,作为子类(派生类),继承人类
public class Teacher extends Person {
}
package 面向对象OOP.继承;

//学生是人,继承人类。
public class Student extends Person {
}
  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合和聚合。
  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
  • 子类和父类之间,从意义上讲应该具有"is a"关系,因为子类只有一个父类。
//子类继承了父类,就会拥有父类的全部方法
package 面向对象OOP.继承;

//人类
public class Person {
    public void say(){
        System.out.println("人类会说话");
    }
}
package 面向对象OOP.继承;

//学生是人,继承人类。
public class Student extends Person {
}//虽然学生类是空的,但还是能够点出say方法,也就是说student类继承了Person类的say方法。
package 面向对象OOP.继承;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();
    }
}

执行结果:

人类会说话
  • private修饰的属性和方法是无法继承的。
  • 不写就是default修饰。
  • protected
  • public,保密性由上之下,由高到低。

②、Object类

  • 快捷键Ctrl+H打开继承树。

在这里插入图片描述

  • ​ 发现父类Person上面还有个Object类
    • 再用Application类调用Person类,发现Person类不止由say()方法可以调用。

在这里插入图片描述

  • 在java中,所有的类都默认继承Object。

③、super关键字

  • super关键字可以在子类中调用父类的方法
package 面向对象OOP.继承;
//父类
//人类
public class Person {
    protected String name = "狂神";
}
package 面向对象OOP.继承;

//学生是人,继承人类。
public class Student extends Person {
    public String name = "秦疆";

    public void test(String name){
        System.out.println(name);//打印输出的是test的实际参数name。
        System.out.println(this.name);//打印输出的是本类中的属性name。
        System.out.println(super.name);//打印出的是其父类Person中的属性name。
    }
}
package 面向对象OOP.继承;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test("张三");//给Student类中的test属性传递了一个实参张三,会输出什么呢?
    }
}
执行结果:
    张三
    秦疆
    狂神
  • super关键字也会在子类中调用父类的属性
//super不仅可以调用父类的属性,也可以调用父类的方法
package 面向对象OOP.继承;
//父类
//人类
public class Person {
    //定义了一个print()方法,输出person。
	public void print(){
        System.out.println("Person");
    }

}
package 面向对象OOP.继承;

//学生是人,继承人类。
public class Student extends Person {
	//在子类中也定义了一个print方法。
    public void print(){
        System.out.println("Student");
    }
    public void test1(){
        print();//调用本类中的print()方法
        this.print();//依然是调用本类中的print()方法,这是this关键字的作用。
        super.print();//调用了父类的方法
    }
}
package 面向对象OOP.继承;

public class Application {
    //执行一下
    public static void main(String[] args) {
        Student student = new Student();
        student.test1();
    }
}
执行结果:
    Student
	Student
	Person

④、关于super的默认情况

//先在父类Person中创建一个显式无参构造方法
package 面向对象OOP.继承;

//人类
public class Person {
    public Person() {
        System.out.println("Person的无参执行了");//方便确认无参方法是否执行
    }
}
//再在子类Student中建立一个显式无参构造方法
package 面向对象OOP.继承;

//学生是人,继承人类。
public class Student extends Person {
    public Student() {
        System.out.println("Student的无参执行了");
    }
}
//在主方法中实例化一个Student变量
//运行并得出结构
package 面向对象OOP.继承;

public class Application {

    public static void main(String[] args) {
        Student student = new Student();
    }
}
执行结果:
    Person的无参执行了
    Student的无参执行了
  • 为什么主方法中明明调用的是Student类的无参构造方法,却先输出了Person的无参构造方法呢?
//答案:
package 面向对象OOP.继承;

//学生是人,继承人类。
public class Student extends Person {
    public Student() {
        super();//正常来说,这个地方应该有个super(),才会使得上面的执行结果成立。
        //这个super()就是被隐藏的代码,它存在,并且必须是在构造器的第一行,放在其他行就会报错。
        System.out.println("Student的无参执行了");
    }
}

⑤、super注意点

  • super调用父类的构造方法,必须在构造方法的第一个。
  • super必须只能出现在子类的方法或者构造方法中。
  • super和this不能同时调用构造方法,因为它们两个都必须放在第一行。
  • super和this的不同点
    • 代表对象不同:this代表本身调用者对象。super代表父类的引用。
    • 前提不同:没有继承也可以使用,super只能在继承条件下才可以使用。
    • 调用构造方法不同:this是调用本类的构造,super是调用父类的构造方法。

⑥、方法重写

  • 子类有和它父类相似的却不同的东西,好比基因突变,青出于蓝而胜于蓝。
package 面向对象OOP.方法重写;

//重写都是方法的重写,和属性无关。
public class B {
    public static void test(){
        System.out.println("B=>test()");
    }
}
package 面向对象OOP.方法重写;
//A类继承B类
public class A extends B{
    public static void test(){
        System.out.println("A=>test()");
    }
}
package 面向对象OOP.方法重写;

public class Application {
    public static void main(String[] args) {
        //方法的调用只和左边定义的数据类型有关
        A a = new A();
        a.test();

        //发现父类B类型的实例b,可以通过A实例化。
        //父类的引用指向了子类。
        B b = new A();//这句没有报错
        b.test();
    }
}
执行结果:
	A=>test()
	B=>test()
  • 快捷键Alt+insert

在这里插入图片描述

  • 非静态(无static)的方法的方法重写
//父类B
package 面向对象OOP.方法重写;

//重写都是方法的重写,和属性无关。
public class B {
    public void test(){
        System.out.println("B=>test()");
    }
}
//子类A继承父类
package 面向对象OOP.方法重写;

public class A extends B{
    //@Override 重写
    @Override//注解:有功能的注释
    public void test() {
        System.out.println("A=>test");
    }
}
//主类:Application
package 面向对象OOP.方法重写;

public class Application {

    //静态方法和非静态方法区别很大!
        //静态方法:方法的调用只和左边有关,是A的就调用A,是B的就调用B。
        //非静态:方法重写。
    public static void main(String[] args) {
        //方法的调用只和左边定义的数据类型有关
        A a = new A();
        a.test();   //A=>test

        //发现父类B类型的实例b,可以通过A实例化。
        //父类的引用指向了子类。
        B b = new A();  //A=>test,子类重写了父类的方法。
        b.test();
    }
}
执行结果:
	A=>test
	A=>test
  • 总结:
    • 需要有继承关系,子类重写父类的方法。
    • 方法名必须相同。
    • 参数列表必须相同。
    • 修饰符范围可以扩大,但不能缩小:public>protected>default>private
    • 抛出的异常:范围可以被缩小,但不能扩大。ClassNotFoundException(小)->Exception(大),可以。
    • 重写:子类的方法和父类的必须要一致,方法体不同!
  • 为什么需要重写?
    • 1、父类的功能,子类不一定需要或者不一定满足!
    • Alt+insert ->override;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值