java中继承:1.super关键字;2.override

本文详细介绍了Java中的继承概念,包括继承的基本语法、特点及其应用。解释了如何使用extends关键字实现类的继承,super关键字的作用,以及方法重写的原则。并通过实例演示了继承在不同场景中的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承
1.1   类和类之间的常见关系。
    1:既然继承是描述类和类之间的关系,就需要先来了解类和类之间的常见关系
1.1.1   现实生活的整体与部分
举例说明
1:现实生活
    1:学生   是人 
    2:狗     是动物
    3:球队 包含 球员 整体与部分的关系,部分可以删除和增加
    4:笔记本包含 cpu 整体与部分的关系,部分不可以删除和增加
    5:航母编队 包含(航母 护卫舰 驱逐舰 舰载机 核潜艇)
1.1.2   java中的类与类关系
java中的类关系
1is a 关系 (学生是人)
2has a 整体与部分
class Person{
    String name;
    int age;
    Address add;
   
    Person(){
      
    }
    Person(String name,int age,Address add){
      
       this.name=name;
       this.age=age;
       this.add=add;
      
    }
   
    void speak(){
       System.out.println("姓名:"+name+" 年龄:"+age+" "+add.print());
    }
}
class Address{
    String country;
    String city;
    String street;
   
    Address(){
   
    }
    Address(String country,String city,String street){
       this.country=country;
       this.city=city;
       this.street=street;
    }
   
    String print(){
       return "地址:"+country+" "+"城市:"+city+街道;"+street;
    }
}
class Demo3{
 
    public static void main(String[] args){
      
       Address add=new Address("中国","广州","棠东东路");
       Person p=new Person("jack",27,add);
       p.speak();
      
      
       System.out.println();
        }
}
   
 
1.2   继承
    1:描述一个学生类
       1:姓名年龄学号属性,学习的方法
    2:描述一个工人类
       1:姓名年龄工号属性,工作的方法
    3:描述一个人类
       1:姓名年龄属性,说话的方法。
4:发现学生类和人类天生有着联系,学生和工人都是人。所以人有的属性和行为学生和工人都会有。出现类代码重复
class Person {
    String name;
    int age;
 
    // 静态变量(类变量)对象和对象之间的代码重复使用静态变量
    static String country = "CN";
 
    Person() {
 
    }
 
    void speak() {
       System.out.println(name + ":哈哈,我是人!!!");
    }
 
}
 
// 让学生类和人类产生关系,发现学生is a 人,就可以使用继承
class Student {
 
    String name;
    int age;
 
    Student() {
 
    }
 
    void study() {
       System.out.println("姓名:" + name + "年纪:" + age + ":好好学习");
    }
}
 
class Worker {
    String name;
    int age;
 
    void work() {
       System.out.println(name + ":好好工作,好好挣钱。");
    }
 
}
 
class Demo1 {
 
    public static void main(String[] args) {
       Student s = new Student();
       s.name = "jack";
       s.age = 20;
       s.study();
 
       Worker w = new Worker();
       w.name = "rose";
 
       w.work();
    }
}
 
    5:问题:
       1:如果没有继承,出现类和类的关系无法描述
       2:如果没有继承,类和类之间有关系会出现类和类的描述代码的重复。
1.3   继承特点
    1:描述类和类之间的关系
    2:降低类和类之间的重复代码
1:降低对象和对象之间的代码重复使用静态变量
    2:降低类和类之间的代码重复使用就继承
   
1.4   extends关键字
继承使用extends关键字实现
1:发现学生是人,工人是人。显然属于is a 的关系,is a就是继承。
2:谁继承谁?
    学生继承人,发现学生里的成员变量,姓名和年龄,人里边也都进行了定义。有重    复代码将学生类的重复代码注释掉,创建学生类对象,仍然可以获取到注释的成员。这就是因为继承的关系,学生类(子类)继承了人类(父类)的部分
class Person {
    String name;
    int age;
 
    // 静态变量(类变量)对象和对象之间的代码重复使用静态变量
    static String country = "CN";
 
    Person() {
 
    }
 
    void speak() {
       System.out.println(name + ":哈哈,我是人!!!");
    }
 
}
 
// 让学生类和人类产生关系,发现学生is a 人,就可以使用继承
class Student extends Person {
 
    Student() {
 
    }
 
    void study() {
       System.out.println("姓名:" + name + "年纪:" + age + ":好好学习");
    }
}
 
class Worker extends Person {
 
    void work() {
       System.out.println(name + ":好好工作,好好挣钱。");
    }
 
}
 
class Demo1 {
 
    public static void main(String[] args) {
       Student stu = new Student();
       stu.name = "jack";
       stu.age = 20;
       stu.study();
        stu.speak();
       System.out.println(stu.country);
       System.out.println(Student.country);
 
       Worker worker = new Worker();
       worker.name = "rose";
       System.out.println(worker.country);
       worker.work();
       worker.speak();
 
       System.out.println();
    }
}
 
继承细节;      
    1:类名的设定,被继承的类称之为父类(基类),继承的类称之为子类
    2:子类并不能继承父类中所有的成员
1:父类定义完整的成员 静态成员,非静态,构造方法。静态变量和静态方
法都可以通过子类名.父类静态成员的形式调用成功。
       2所有的私有成员不能继承,private修饰的成员。
       3构造函数不能被继承
 
    3:如何使用继承
1:不要为了使用继承而继承。工人和学生都有共性的成员,不要为了节省代
码,让工人继承学生。
/*
如何使用继承:验证是否有 is  a 的关系
 例如:学生是人, 小狗是动物
 注意:不要为了使用某些功能而继承,java只支持单继承
 */
class DK {
 
    void Ip4S() {
       System.out.println("好玩");
    }
}
 
class BGir extends DK {
 
}
 
class Demo {
 
    public static void main(String[] args) {
 
       new BGir().Ip4S();
 
    }
}
 
1.5super关键字
    1:定义Father(父类)
       1:成员变量int x=1;
       2:构造方法无参的和有参的,有输出语句
    2:定义Sonextends Father
       1:成员变量int y=1;
       2:构造方法无参和有参的。有输出语句
       1this.y=y+x;
    3:创建Son类对象
       Son son=new Son(3);
       System.out.println(son.y); //4
class Father {
    int x = 1;
 
    Father() {
       System.out.println("这是父类无参构造");
    }
 
    Father(int x) {
 
       this.x = x;
       System.out.println("这是父类有参构造");
    }
 
    void speak() {
       System.out.println("我是父亲");
    }                 
}
 
class Son extends Father {
    int y = 1;
 
    Son() {
       System.out.println("这是子类的无参构造");
    }
 
    Son(int y) {
 
       this.y = y + x;
       System.out.println("这是子类的有参构造");
    }
 
    void run() {
       super.speak(); // 访问父类的函数
       System.out.println("我是儿子");
    }
}
 
class Demo6 {
 
    public static void main(String[] args) {
       Son s = new Son(3);
       System.out.println(s.y);// 4
    }
}
 
    4:子类对象为什么可以访问父类的成员。
       1this.y=y+x;有一个隐式的super super.x
 
    5super关键字作用
       1:主要存在于子类方法中,用于指向子类对象中父类对象。
       2:访问父类的属性
       3:访问父类的函数
       4:访问父类的构造函数
    6super注意

super关键字调用父类构造方法要注意的事项:
1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。
2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句
3. super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。(this.name = name可以)


thissuper很像,this指向的是当前对象的调用,super指向的是当前调用对象的父类。Demo类被加载,执行main方法,Son.class加载,发现有父类Father类,于是Father类也加载进内存。类加载完毕,创建对象,父类的构造方法会被调用(默认自动无参),然后执行子类相应构造创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部。this super只能在有对象的前提下使用,不能在静态上下文使用。
2:子类的构造函数默认第一行会默认调用父类无参的构造函数,隐式语句
super();
           1:父类无参构造函数不存在,编译报错。
  
Son(int y) {
       //super();隐式语句
       this.y = y + x;
       System.out.println("这是子类的有参构造");
    }
 
    3:子类显式调用父类构造函数
在子类构造函数第一行通过super关键字调用父类任何构造函数。如果显式调用父类构造函数,编译器自动添加的调用父类无参数的构造就消失。构造函数间的调用只能放在第一行,只能调用一次。super() this()不能同时存在构造函数第一行。
Son(int y) {
       super(y);// 子类显式调用父类构造函数
       this.y = y + x;
       System.out.println("这是子类的有参构造");
    }
 
Son(int y) {
       this();  //不能同时存在构造函数第一行 
       super(y);
       this.y = y + x;
       System.out.println("这是子类的有参构造");
    }
 
    4super思考
如果开发者自定义了一个类,没有显示的进行类的继承,那么该类中成员函数是否可以使用super关健健字?可以使用,继承了Object类,Object类是所有类的父类。
class Demo7 {
    public  void print(){
       System.out.println(super.toString());
    }
    public static void main(String[] args){
       new Demo7().print();
       System.out.println();
        }
}
 
    5:继承练习
   
重写(Override

方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。

什么是时候要使用方法的重写:父类的功能无法满足子类的需求时。

1:定义Father
    1:姓名,吃饭方法,吃窝窝头。
    2:定义Son类,继承Father
       1Son类中不定义任何成员,子类创建对象,仍然可以调用吃饭的方法。
       2:父类的吃饭的方法,Son不愿吃。Son自己定义了吃饭的方法。
1:此时父类中有一个吃饭的方法,子类中有2个吃饭的方法,一模一样,只是方法体不一样。
           2:一个类中两个函数一模一样,是不允许的。
              1:编译运行,执行了子类的方法。
              2:使用父类的方法,在子类方法中,使用super.父类方法名。
class Father {
    String name;
 
    void eat() {
       System.out.println("吃窝窝");
    }
}
 
class Son extends Father {
 
    public void eat() { // 继承可以使得子类增强父类的方法
       System.out.println("来俩小菜");
       System.out.println("来两杯");
       System.out.println("吃香喝辣");
           System.out.println("来一根");
    }
}
 
class Demo8 {
 
    public static void main(String[] args) {
       Son s = new Son();
        //执行子类的方法
       s.eat();
 
    }
}
 
3:该现象就叫做重写(覆盖 override)
1 在继承中,子类可以定义和父类相同的名称且参数列表一致的函数,将这种函数
称之为函数的重写.
4:前提
    1:必须要有继承关系
5:特点
1:当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数。
       可以通过super关键字进行父类的重写函数的调用。
    2 继承可以使得子类增强父类的方法
6:细节
    1 函数名必须相同
    2:参数列表必须相同
3 子类重写父类的函数的时候,函数的访问权限必须大于等于父类的函数的访
问权限否则编译报错
4:子类重写父类的函数的时候,返回值类型必须是父类函数的返回值类型或该返回值类型的子类。不能返回比父类更大的数据类型: 如子类函数返回值类型是Object
 
       1:定义 A B  C B extends A 
       2Father类中定义A getA();
       3Son 类中重写getA(); 方法,尝试将返回值修改为BC ,Object
           1B编译通过
           2C 编译失败 ,没有继承关系
           3Object编译失败,比父类的返回值类型更大
class A {
 
}
 
class B extends A {
 
}
 
class C {
 
}
class Father {
    String name;
 
    void eat() {
       System.out.println("吃窝窝");
    }
 
    // 定义一个函数,获取A类的对象,
    A getA() {
       return new A();
    }
 
}
 
class Son extends Father {
 
    public void eat() { // 继承可以使得子类增强父类的方法
       System.out.println("来两杯");
       System.out.println("来俩小菜");
       super.eat();
       System.out.println("来一根");
    }
 
    // B类是A类的子类
    B getA() {
       return new B();
    }
}
 
class Demo8 {
 
    public static void main(String[] args) {
       Son s = new Son();
       s.eat();
 
    }
}
 
7:子类对象查找属性或方法时的顺序:
    1:原则:就近原则。
如果子类的对象调用方法,默认先使用this进行查找,如果当前对象没有找到属性或方法,找当前对象中维护的super关键字指向的对象,如果还没有找到编译报错,找到直接调用。
8重载和重写的不同
    方法重写要注意的事项:
1.方法重写时, 方法名与形参列表必须一致。
2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。
3.方法重写时,子类的返回值类型必须要小于或者 等于父类的返回值类型。
4.方法重写时, 子类抛出的异常类型要小于或者等于父类抛出的异常类型。
Exception(最坏)
RuntimeException(小坏)

方法的重载:在一个类中 存在两个或者两个 以上的同名函数,称作为方法重载。

方法重载的要求
1. 函数名要一致。
2. 形参列表不一致(形参的个数或形参 的类型不一致)
3. 与返回值类型无关。
9:重写练习
       描述不同的动物不同的叫法
       1:定义动物类
           有名字,有吃和叫的方法
       2:定义狗继承动物重写父类吃和叫的方法
       3:定义猫继承动物重写父类吃和叫的方法
class Animal{
    int x=1;
    String name;
   
    void eat(){
       System.out.println("吃东西");
    }
    void shout(){
       System.out.println("我是动物");
    }
}
 
class Dog extends Animal{
   
   
    void eat(){
       System.out.println("啃骨头");
    }
    void shout(){
       System.out.println("旺旺");
    }
    void eat(String food){
       System.out.println("吃:"+food);
    }
}
class Cat extends Animal{
 
    void eat(){
       System.out.println("吃老鼠");
    }
    void shout(){
       System.out.println("喵喵");
    }
}
 
class Demo9{
 
    public static void main(String[] args){
       Dog d=new Dog();
       d.shout();
       d.eat();
      
       Cat c=new Cat();
       c.shout();
       c.eat();
       System.out.println();
        }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值