继承+super

2.继承

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

◆extends的意思是“扩展”。子类是父类的扩展。

◆JAVA中类只有单继承,没有多继承!

父类Person

package com.oop.demo02;
//是学生、老师类的父类
//子类可以继承父类方法和属性(public)
/*
* public
* protected
* default  什么都没写 就是default这个
* private
* */
public class Person {public int legacy=10_0000_0000;//这里定义的是public的变量private  int estate=20_0000_0000;//这里定义的是私有属性,不给子类使用//注意这里的say方法是public修饰的public void say(){System.out.println("我说了一句话!");}
}

子类学生类 Student

package com.oop.demo02;
//学生继承了人  这个类  是person的子类/派生类
public class Student extends Person{//Person person;  //组合,暂时还不知道什么意思
}

子类教师类

package com.oop.demo02;
//老师类继承了 人这个类   是person的子类
public class Teacher extends Person {}

启动类Application

package com.oop.demo02;
//启动类(包内包外都可以  import(包外))
//Demo02  面向对象 继承
//object类
//这是包外启动项  主要想测试下 import
//还有public 等关键字
//Crtl+H 打开结构树
//在java的类都默认直接或者间接继承Object类!
//java中只有单继承,没有多继承  一个儿子只能有一个爸爸,但是一个爸爸可以有多个儿子
public class Application {public static void main(String[] args) {Student s1 = new Student();s1.say();//这个方法是Student继承了人这个类的System.out.println(s1.legacy);//继承了父类的属性//System.out.println(s1.estate);//私有的不给子类用Teacher t1 = new Teacher();t1.say();//同理t1继承了人这个类的say方法System.out.println(s1.legacy);//继承了父类的属性}
}

◆继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等
◆继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
◆子类和父类之间,从意义上讲应该具有"is a"的关系.

◆object类
◆super

父类Person

package com.oop.demo03;public class Person {protected String name="巢安龙";private int age=20;protected void print(){System.out.println("Person");}
}

子类学生类Student

package com.oop.demo03;
//继承的的包内Demo03 的 Person类
public class Student extends Person {
public String name="胖呼呼";public void test(String name){System.out.println(name); //打印传进来的形参的 nameSystem.out.println(this.name);//打印实例化对象的 nameSystem.out.println(super.name);//打印父类的 name}public void print(){System.out.println("Student");}public void print_new(String content){System.out.println(content);print();this.print();super.print();//调用父类的方法}}

子类教师类 Teacher

package com.oop.demo03;
//继承的的包内Demo03 的 Person类
public class Teacher extends Person{
public String name="longGe";
public void test(String name){System.out.println(name); //打印传进来的形参的 nameSystem.out.println(this.name);//打印实例化对象的 nameSystem.out.println(super.name);//打印父类的 name}}

应用类Application

package com.oop.demo03;//这里主要突出 继承super 的
//super 指代实例化对象的父类  可以调用父类的属性和方法(当然私有的private 无法被继承)
//this 指代当前实例化对象
public class Apllication {
public static void main(String[] args) {Student student = new Student();//super 调用父类的属性(private的不行)student.test("癞痢皮");Teacher teacher = new Teacher();teacher.test("chaoGe");//这两个方法名竟然可以一样//student.super//为什么在测试类里面用不了super 还是我的使用方法出了问题呢?//super 调用父类里面的方法! 看Student类里面的详细实现student.print_new("student_content");}}

输出结果:

癞痢皮
胖呼呼
巢安龙
chaoGe
longGe
巢安龙
student_content
Student
Student
Person

为什么在测试类里面用不了super 还是我的使用方法出了问题呢?

package com.oop.Demo03;//这里主要突出 继承super 的
//super 指代实例化对象的父类  可以调用父类的属性和方法(当然私有的private 无法被继承)
//this 指代当前实例化对象
public class Apllication {public static void main(String[] args) {Student student = new Student();//student.test("癞痢皮");//Teacher teacher = new Teacher();//teacher.test("chaoGe");//这两个方法名竟然可以一样student.super//为什么在测试类里面用不了super 还是我的使用方法出了问题呢?}
}

在你的代码中,super 是一个关键字,用于引用父类(超类)中的构造方法、属性和方法。在 Java 中,super 不能在实例化对象的类方法中直接使用,而是用于访问当前对象的父类成员。

为什么你无法在 Apllication 类中使用 super

  1. super 只能在 子类的实例方法中使用,目的是访问父类的成员(方法、变量、构造器等)。你不能在父类(如 Apllication 类)的 main 方法中直接使用 super,因为 main 方法是静态方法,它并不属于任何具体的实例对象。
  2. 如果你希望使用 super,你需要在 子类中编写方法,使用 super 来访问父类的成员。

使用 super 的正确方法:

  1. 父类和子类的关系:子类通过继承父类,可以访问父类的公开成员(publicprotected)以及父类提供的方法和构造器。private 成员是不能被继承的,因此 super 无法访问它们。
  2. super 用法示例
    • 在子类中,使用 super() 调用父类构造器。
    • 使用 super.属性super.方法 来调用父类的成员或方法。

代码示例

假设你有一个父类 Person,和一个子类 Student,你可以在子类中使用 super 来访问父类的成员。

父类 Person

package com.oop.Demo03;public class Person {protected String name; // protected 使得子类可以访问protected int age;public Person(String name, int age) {this.name = name;this.age = age;}public void introduce() {System.out.println("我叫 " + name + ",年龄 " + age);}
}

子类 Student

package com.oop.Demo03;public class Student extends Person {private String school;public Student(String name, int age, String school) {// 调用父类的构造方法super(name, age);//必须放在这个方法提第一行this.school = school;}public void introduce() {// 调用父类的 introduce 方法super.introduce();  // 访问父类的成员方法System.out.println("我来自 " + school);}
}

测试类 Application

package com.oop.Demo03;public class Application {public static void main(String[] args) {Student student = new Student("张三", 20, "清华大学");student.introduce();}
}

解释:

  1. super(name, age):在 Student 的构造方法中,super 用来调用父类 Person 的构造方法,以初始化父类的 nameage 属性。
  2. super.introduce():在 Studentintroduce 方法中,通过 super.introduce() 调用父类 Personintroduce 方法。
  3. super 在子类中使用super 用于子类中访问父类的成员或构造方法,但不能在父类(如 Application 类)中使用。

你的错误:

你在 Application 类的 main 方法中尝试使用 super,这是不允许的。因为 super 是用来指代子类对象的父类成员的,所以它只能在子类的实例方法中使用。

1. 如果没有定义构造器,Java 会默认提供一个无参构造器

  • 正确,如果你没有定义任何构造器,Java 会自动提供一个无参构造器,且该构造器什么都不做。
public class Person {private String name;// Java 会自动提供如下无参构造器// public Person() { }
}

你可以通过以下方式创建对象:

Person person = new Person();  // 调用自动生成的无参构造器

1.1 如果没有显式写无参构造器,也能直接创建对象

  • 正确,如果你没有定义任何构造器,Java 会自动提供一个无参构造器。
  • 你可以直接用 new 创建对象,而不需要显式定义无参构造器。
public class Person {private String name;// 没有显式定义构造器,Java 会提供一个默认的无参构造器
}Person person = new Person();  // 正常创建对象

1.2 如果你定义了有参构造器,就不会自动提供无参构造器

  • 正确,当你定义了有参构造器后,Java 不会再自动提供无参构造器。如果此时你希望使用无参构造器,你必须显式定义它,否则会报错。
public class Person {private String name;// 显式定义了有参构造器public Person(String name) {this.name = name;}
}// 这会报错:因为没有无参构造器
Person person = new Person();  // 编译错误

如果你希望仍然能使用无参构造器来创建对象,就必须显式定义一个无参构造器:

public class Person {private String name;// 无参构造器public Person() {this.name = "默认名字";}// 有参构造器public Person(String name) {this.name = name;}
}Person person1 = new Person();       // 使用无参构造器
Person person2 = new Person("张三");  // 使用有参构造器

1.3 子类创建对象时会默认先调用父类的构造器,默认调用父类的无参构造器

  • 正确当你创建一个子类对象时,Java 会默认调用父类的构造器。如果父类没有无参构造器,且你没有显式调用父类的有参构造器,就会报错。
  • 如果父类只有有参构造器,而没有无参构造器,子类的构造器必须显式调用父类的有参构造器。
public class Person {private String name;// 只有有参构造器public Person(String name) {this.name = name;}
}public class Student extends Person {// 子类无参构造器public Student() {// 必须显式调用父类的有参构造器super("张三");  // 调用父类的有参构造器}
}// 这样可以创建 Student 对象
Student student = new Student();  // 正常创建对象,调用了父类的有参构造器

如果你没有在子类构造器里显式调用父类的构造器,且父类没有无参构造器,就会编译错误。

总结:

  1. 如果你没有定义构造器:Java 会自动提供一个无参构造器。
  2. 如果你定义了有参构造器:Java 不会自动提供无参构造器。如果需要无参构造器,你必须显式定义。
  3. 如果子类创建对象时,父类没有无参构造器:Java 会默认调用父类的无参构造器。如果父类没有无参构造器,子类必须显式调用父类的有参构造器(super(参数))。
  4. 子类创建对象时,必须先调用父类构造器,否则会报错,特别是在父类没有无参构造器时,必须显式调用父类的有参构造器。

是不是在自己写类的时候最好显式加无参构造器

在自己编写类时,是否显式添加无参构造器通常取决于几个因素,特别是你希望如何使用这个类,以及它的继承关系。总体而言,在大多数情况下,显式地添加无参构造器是一个好习惯,尤其是在以下几种场景中:

1. 需要使用无参构造器时

如果你希望通过无参构造器创建对象,或者某些库和框架(如 Java 序列化、反射、Spring 等)需要无参构造器来实例化类,显式定义一个无参构造器就非常重要。例如:

  • 反射:有些框架或工具会通过反射来创建对象,这时需要有一个无参构造器。
  • 序列化和反序列化:Java 的序列化机制通常会要求类有一个无参构造器,因为反序列化时需要先创建对象然后再设置字段的值。

2. 继承关系中的构造器调用

如果你的类作为父类被继承,子类默认会调用父类的构造器。如果父类没有显式定义无参构造器,且子类没有显式调用父类的有参构造器,子类的构造器会报错。因此,在父类中定义无参构造器可以避免一些潜在的错误。

3. 给类添加默认行为或值

无参构造器通常用于设置类的默认状态,尤其是在没有外部输入的情况下。例如:

public class Person {private String name;private int age;// 无参构造器,设置默认值public Person() {this.name = "未知";this.age = 0;}// 有参构造器,允许外部设置值public Person(String name, int age) {this.name = name;this.age = age;}
}

在这个例子中,使用无参构造器会创建一个默认值的 Person 对象,而有参构造器可以根据需要设置特定的值。

4. 兼容性

如果你将这个类交给其他开发人员使用或集成到框架中,添加无参构造器会提供更高的兼容性。这样,无论是框架,还是其他开发人员都能更方便地创建对象。

5. 反序列化和 JSON 处理

在处理 JSON 时,比如使用 JacksonGson 等库,它们会使用无参构造器来创建对象,然后通过 setter 方法或字段直接填充数据。如果没有无参构造器,反序列化可能会失败。

6. 避免潜在问题

如果类没有无参构造器且又没有显式地在其他构造器中调用父类的构造器,子类可能会无法正确实例化。因此,明确地定义一个无参构造器可以避免这种潜在的错误。

7. 特殊情况:当你有复杂初始化逻辑时

如果你的类有一些复杂的初始化逻辑,而无参构造器的行为难以保证,可能需要避免使用无参构造器。例如,当类需要接收特定的依赖项(如数据库连接、外部服务等)时,最好使用有参构造器来确保类在创建时得到正确的初始化。

小结:是否显式添加无参构造器

  • 推荐做法在多数情况下,尤其是类有多个构造器时,显式添加无参构造器是一个好习惯。这样做不仅能提供更好的兼容性,还能避免继承时的构造器问题。
  • 例外情况如果类的构造过程非常复杂,或者你不希望允许无参实例化对象(比如不想创建空对象),则可以选择不定义无参构造器。

总之,虽然 Java 编译器会在某些情况下自动提供无参构造器,但为了明确控制对象创建过程,并提高代码的可维护性和兼容性,显式添加无参构造器是一个值得推荐的做法。

super注息点:
1.super调用父类的构造方法,必须在构造方法的第一个

2.super 必须只能出现在子类的方法或者构造方法中!

3、super和 this 不能同时用构造方法!
Vs this:

代表的对象不同:this: 本身调用者这个对象super:代表父类对象的应用

前提

this:没有继承也可以使用super:只能在继承条件才可以使用构造方法
this();本类的构造super():父类的构造!

继承中构造器执行顺序

父类 Person

package com.oop.demo04;public class Person {private String name;//无参构造器 构造方法public Person() {System.out.println("Person无参构造执行了!");}//Person的有参构造器public Person(String name) {this.name = name;}
}

子类学生类 Student

package com.oop.demo04;//继承的的包内Demo04 的 Person类
public class Student extends Person {private String name;//无参构造器  无参构造方法public Student() {//隐藏代码,可以不写的//super();//调用父类的构造器必须要在子类的第一行 所以如果父类定义了有参却没有定义无参 子类初始化就会报错//this("巢安龙");//调用本类的构造器(有参/无参) 本类的第一行// 由于继承了父类 所以子类创建对象时调用了构造器,就会会默认调用父类的无参,如果无参没有初始化就会报错
//解决办法 手动添加无参构造  或者直接调用父类的有参构造(有的话)super();//这是直接调用父类的无参构造器 继承的话 这句是可以省略的 但是如果写了就得放在此方法体的第一行//super("perple's name");//调用父类的构造器也必须要在子类的第一行System.out.println("Student无参构造执行了!");}public Student(String name) {//这里父类没有无参构造器 得加一句 super(参数)父类的有参构造器(有的话)super("name");this.name=name;}
}

子类教师类 Teacher

package com.oop.demo04;//继承的的包内Demo04 的 Person类
public class Teacher extends Person {public Teacher() {super();}public Teacher(String name) {super("name");}
}

启动类Application

package com.oop.demo04;//这里主要突出 继承super 的
//此软件包主要突出 super 对构造器的影响
//alt +insert 快捷插入构造器
public class Apllication {public static void main(String[] args) {Student student = new Student();//这里实例化Student类 调用其无参构造器,但是由于Student类继承了Person类,所以调用Student无参构造的时候也调用了Person的无参构造器}
}

输出结果:

Person无参构造执行了!
Student无参构造执行了!

注意点:

关键点:

  1. super() 关键字
    • 用于在子类构造器中调用父类构造器。
    • super() 调用父类的无参构造器,super(参数) 调用父类的有参构造器。
  2. 构造器调用顺序
    • 子类构造器首先调用父类构造器(无参或有参),然后执行子类构造器的内容。
    • super() 必须是子类构造器的第一行代码。
  3. 继承中的构造器
    • 如果父类没有无参构造器,子类必须显式调用父类的有参构造器。
    • 如果子类没有显式调用父类构造器,Java 会默认调用父类的无参构造器(前提是父类有无参构造器)还是那个问题,子类不用父类有参构造,会默认调用父类无参,此时如果父类有有参构造器又没有无参构造器,那就要么添加父类无参构造器,或者显式调用定义好的父类有参构造器
  4. 默认构造器
    • 如果子类没有定义构造器,Java 会提供一个默认的无参构造器,自动调用父类的无参构造器。
    • 如果父类没有无参构造器,则子类必须显式调用父类的有参构造器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/868222.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AT_abc388_f Dangerous Sugoroku 题解

太幽默了。 显然可以用矩阵快速幂解决,矩阵里维护距离当前点 \(B\) 以内的所有点可不可达,转移只需分段,在区间内和不在区间内用不同的转移矩阵即可。复杂度 \(O(B^3m\log n)\)。 然后你就 T 了。 此时你很急,你现在应该快点卡常来 AK 这场比赛而不是研究其他的做法,于是我…

多路复用与多路分解

主机维护一个Socket表,通过表中记录的ipport与socket对应关系进行封装报文,接受到报文时使用报文的ip和port查找对应socket的过程 称为多路复用与多路分解 TCP socket存有本机进程到对端进程的映射关系UDPudp是无连接的,本机ip port没有和对端ip port构成映射关系,udp的soc…

计算机网络-多路复用与多路分解

主机维护一个Socket表,通过表中记录的ipport与socket对应关系进行封装报文,接受到报文时使用报文的ip和port查找对应socket的过程 称为多路复用与多路分解 TCP socket存有本机进程到对端进程的映射关系UDPudp是无连接的,本机ip port没有和对端ip port构成映射关系,udp的soc…

.NET 中管理 Web API 文档的两种方式

前言 在 .NET 开发中管理 Web API 文档是确保 API 易用性、可维护性和一致性的关键。今天大姚给大家分享两种在 .NET 中管理 Web API 文档的方式,希望可以帮助到有需要的同学。 Swashbuckle Swashbuckle.AspNetCore 是一个流行的 .NET 库,它使得在 ASP.NET Core 项目中自动生…

idea设置快捷键

idea设置快捷键 下载安装idea 参考:pyhton、miniConda、pycharm下载安装配置中的pycharm下载安装配置即可,jetbrains系列软件都可如此操作。 查询快捷键 打开安装好的idea, ctrl+alt+s或手动打开Settings/设置, 点击左侧Keymap/按键映射页签, 点击右侧搜索框右侧的放大镜,…

抖音评论生成器在线工具,好评生成器软件,用js+html即可实现

开发技术HTML:用于搭建页面结构。 CSS:用于美化页面样式。 JavaScript:实现核心逻辑,包括文案生成、随机选择、复制功能等。 部分框架代码:<!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name=…

Odoo18.0附件分享管理

需求背景 虽然odoo官方提供了文档的门户访问功能,外部用户可以在门户查看共享的文档和相关的附件。但是某些情况下,我们希望外部用户只能有限地能访问我们指定的附件,而不是能够访问整个文档和全部附件。 本文即是介绍为了解决此问题而开发的功能。 功能介绍 这里我们以销售…

git worktree同一个仓库多个分支并行开发和管理

Git Worktree 是 Git 提供的一个功能,允许你在同一个仓库中同时工作在多个工作目录中,每个目录都有自己的工作树和索引。这对于同时处理多个分支或版本非常有用。介绍 Git Worktree 是 Git 提供的一个功能,允许你在同一个仓库中同时工作在多个工作目录中,每个目录都有自己的…

idea汉化教程,jetbrains系列软件都适用

idea汉化教程,jetbrains系列软件都适用 下载安装idea 参考:pyhton、miniConda、pycharm下载安装配置中的pycharm下载安装配置即可,jetbrains系列软件都可如此操作。 汉化 打开安装好的idea, ctrl+alt+s或手动打开Settings/设置, 点击左侧Plugins/插件页签, 点击右侧Market…

搭建jumpserver堡垒机--基本使用(三)

一.给所有服务器设置只允许jumpserver机器登录(尽量不要操作)1.开放堡垒机ssh登录,xxx.xxx.xxx.xxx对应堡垒机ipiptables -A INPUT -s xxx.xxx.xxx.xxx -p tcp --dport 22 -j ACCEPT2.拒绝所有机器ssh登录iptables -A INPUT -p tcp --dport 22 -j REJECT 二. 配置邮箱和创建用…

【学习笔记】斜率优化 dp

LearningForeword 斜率优化,顾名思义就是用一次函数的单调性来优化 dp,具体表现为利用单调性找到最优决策点从而优化掉需要枚举的决策点。 给斜率优化 dp 总结一个模板: \[dp_{i} = \min\{dp_{j} + calc (i,j)\} \]或者: \[dp_{i} = \max\{dp_{j} + calc (i,j)\} \]其中 \(…

安装MM系统(使用systemback封装Ubuntu系统iso镜像)

哈喽啊亲们!今天又是阳光明媚的一天,不知道亲们想me了没,今天小橘给大家分享一下MM系统镜像的封装流程,欢迎大家一起探讨。一、安装 MM 系统到其他机器的硬盘上 (一) BMC 挂载镜像 设置--一般--媒体重定向设置--一般设置--远程媒体支持--挂载 CD/DVD--填写信息--保存--选择…