JAVA面向对象(下 )(一、继承和方法重写)

一、继承

1.1 什么是继承

生活中继承是指:

  • 继承财产=>延续财产

  • 继承/遗传 父母的长相,基因 => 延续上一代的基因

  • 继承技能、专业、职位 =>延续

  • 继承中华民族的传统文化 => 延续

  • 青出于蓝而胜于蓝 或 长江后浪推前浪,前浪被拍在沙滩上 => 下一代比上一代更厉害

Java中继承是指:

  • 代码的复用:子类可以继续使用父类已经声明过的代码

  • 代码的扩展:子类比父类对事物的描述更具体,更丰富,(属性或功能更多)

  • is-a 的关系:子类是父类事物的一个分支

示例代码
父类Person
package com.atguigu.inherited;public class Person {//父类//属性public String name;public int age;//方法public void eat(){System.out.println(name+"现在是" + age +"岁,在吃东西");}
}
子类Student
package com.atguigu.inherited;//Student是子类
//Person是父类
//子类继承了父类的成员,代码的复用
//子类和父类不同,子类的成员比父类多,子类更具体
public class Student extends Person{//属性public int score;//成绩//方法public void exam(){System.out.println(name+"现在是" + age +"岁,在在考试");}
}
测试类TestStudent
package com.atguigu.inherited;public class TestStudent {public static void main(String[] args) {//Person对象只能访问name,age属性,调用eat()方法Person p = new Person();p.name = "李四";p.age = 24;p.eat();System.out.println("=========================");//Student对象可以访问name,age,score属性,调用eat()和exam()方法Student s = new Student();s.name = "张三";s.age = 23;s.score = 99;//父类已经声明过了,从父类继承的s.eat();//父类已经声明过了,从父类继承的s.exam();}
}

1.2 如何继承?

语法格式:

【修饰符】 class 父类名{}
【修饰符】 class 子类名 extends  父类名{ //extends是关键字}

父类:SuperClass,又称为超类,基类。

子类:SubClass,又称为派生类。

extends:扩展

1.3 继承有什么特点或要求

1、Java中只支持单继承

比喻:每一个人只有一个亲生父亲。

【修饰符】 class 子类名 extends  父类名1, 父类名2{ //错误}

2、Java中支持多层继承

比喻:代代相传。

解释:父类也可以有父类,父类的父类对于这个子类来说也是父类。

public class A{}
public class B extends A{}
public class C extends B{}
//B是C的父类,它是C的直接父类。
//A也是C的父类,它是C的间接父类。
//B会继承A的成员,然后C会继续继承B的成员。C的成员最多。

3、同一个父类可以同时有多个子类

比喻:支持多胎。

public class A{}
public class B extends A{}
public class C extends A{}
//B和C同时都是A的子类,而且是并列关系。B和C是兄弟类关系。

4、父类的所有成员变量、成员方法会继承到子类吗?

父类的所有成员变量、成员方法,都会继承到子类中。但是,父类中私有的成员变量,成员方法,子类不能直接使用,如果子类需要使用,直接通过间接的方式使用,例如:通过get/set方式。

Father类
package com.atguigu.inherited;public class Father {//父类//这四个属性的权限修饰符是不同的public int a;int b;protected int c;private int d;public int getD(){return d;}public void setD(int d) {this.d = d;}
}
Son类
package com.atguigu.inherited;//Son是子类,Father是父类
public class Son extends Father {private int e;public void setE(int e) {this.e = e;}public String getInfo() {
//        return "a = " + a + ",b = " + b + ",c= " + c + ",d = " + d + ",e = " + e;//d因为在父类中是private修饰,所以在子类中无法直接使用return "a = " + a + ",b = " + b + ",c= " + c + ",d = " + getD() + ",e = " + e;}
}
测试类TestSon
package com.atguigu.inherited;public class TestSon {public static void main(String[] args) {Son s = new Son();s.a = 1;s.b = 1;s.c = 1;
//        s.d = 1;
//        s.e = 1;s.setD(1);s.setE(1);System.out.println(s.getInfo());}
}

5、父类的构造器会继承到子类吗?

父类的构造器不会继承到子类中,但是,子类的构造器中必须调用父类的构造器。

  • 不会继承的原因:父类的构造器是用来创建父类的对象的

  • 必须调用的原因:父类的构造器中 编写了 为父类中声明的这些属性初始化的代码,那么子类会继承这些属性,就需要“复用”父类构造器的这些代码为它们初始化。

说明:

  • 子类的构造器==默认==去找父类的无参构造。

  • 当然,子类构造器也可以通过 super(); 或 super(实参列表); 来明确子类找父类的哪个构造器

    • super(); 明确调用父类的无参构造

    • super(实参列表); 明确调用父类的有参构造

父类Animal
package com.atguigu.inherited;public class Animal {//父类,Animal:动物private String name;private int age;public Animal() {System.out.println("父类Animal的无参构造");}public Animal(String name, int age) {System.out.println("父类Animal的有参构造");this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
子类Dog
package com.atguigu.inherited;//Dog是子类
//Animal是父类
public class Dog extends Animal{//Dog:狗private double weight;//重量public Dog() {super();//这句话可以省略,表示默认调用父类的无参构造//super("小黑",1);System.out.println("子类Dog的无参构造");}public Dog(String name, int age, double weight) {super(name, age);//明确说明调用父类的有参构造,为name和age属性初始化//super();System.out.println("子类Dog的有参构造");this.weight = weight;}
}
测试类TestDog
package com.atguigu.inherited;public class TestDog {public static void main(String[] args) {Dog d1 = new Dog();Dog d2 = new Dog("小白",3,5.6);}
}
思考题1

问:子类的无参构造一定找父类的无参构造,子类的有参构造一定找父类的有参构造?没有

思考题2

问:父类没有无参构造,会怎么样?

6、子类可以重写父类的方法

请看$1.4小节。

1.4 方法的重写

如果父类的某个成员方法,继承到子类后,子类认为该方法的方法体功能实现不适合子类,子类可以选择对其进行重写(Override)。

1.4.1 重载与重写的区别

方法的重载(Overload)方法的重写(Override)
2个或多个方法的位置在同一个类中 或 父子类中父子类中
修饰符不看必须满足> 或 =的关系
返回值类型不看void:必须相同 基本数据类型:必须相同 引用数据类型:必须满足 < 或 = 的关系
方法名必须相同必须相同
(形参列表)必须不同。个数、类型、顺序不同,和形参名无关。必须相同。个数、类型、顺序相同,和形参名无关。
{方法体}不看必须重写实现

示例代码1
父类Fu1
package com.atguigu.override;public class Fu1 {//父类public void m1(){System.out.println("Fu.m1方法");}protected void m2(){System.out.println("Fu.m2方法");}void m3(){System.out.println("Fu.m3方法");}private void m4(){System.out.println("Fu.m4方法");}
}
子类Zi1
package com.atguigu.override;//Zi是子类,Fu是父类
public class Zi1 extends Fu1{//因为父类Fu1的m1方法的权限修饰符是public//子类Zi1的m1方法,权限修饰符必须是public@Overridepublic void m1(){System.out.println("Zi.m1方法");}//因为父类Fu1的m2方法的权限修饰符是protected//子类Zi1的m2方法,权限修饰符可以是public 或 protected@Overridepublic void m2(){System.out.println("Zi.m2方法");}//因为父类Fu1的m3方法的权限修饰符是缺省//子类Zi1的m3方法,权限修饰符可以是public 或 protected 或缺省@Overridevoid m3(){System.out.println("Zi.m3方法");}//不是重写,因为父类Fu1的m4方法,在子类中不可见//@Override //加它会报错,因为现在的m4方法不是重写,它只是子类Zi1自己定义的一个方法private void m4(){System.out.println("Zi.m4方法");}
}
父类Fu2
package com.atguigu.override;public class Fu2 {public void m1(){System.out.println("Fu.m1的方法");}public int m2(){System.out.println("Fu.m1的方法");return 0;}public Object m3(){System.out.println("Fu.m3的方法");return new Object();}public String m4(){System.out.println("Fu.m4的方法");return new String();}
}
子类Zi2
package com.atguigu.override;public class Zi2 extends Fu2{//因为Fu2类的m1方法的返回值类型是void//Zi2的m1方法的返回值类型只能是voidpublic void m1(){System.out.println("Zi.m1的方法");}//因为Fu2类的m2方法的返回值类型是int//Zi2的m2方法的返回值类型只能是intpublic int m2(){System.out.println("Zi.m2的方法");return 1;}//因为Fu2类的m3方法的返回值类型是Object//Zi2的m3方法的返回值类型可以是Object,或 Object的子类//String < Objectpublic String m3(){System.out.println("Zi.m3的方法");return  new String();}//因为Fu2类的m4方法的返回值类型是String//Zi2的m4方法的返回值类型可以是String,或String的子类//很遗憾,String没有子类,它是太监类public String m4(){System.out.println("Zi.m4的方法");return new String();}
}
父类Fu3
package com.atguigu.override;public class Fu3 {public void m1(){System.out.println("Fu.m1");}public void m2(int a, int b){System.out.println("Fu.m2");}public void m3(int a, int b){System.out.println("Fu.m3");}
}
子类Zi3
package com.atguigu.override;public class Zi3 extends Fu3{//因为Fu3的m1方法的形参列表是(),//那么Zi3的m1方法如果是()就是重写,如果是(非空)就是重载public void m1(int a){System.out.println("Zi.m1");}//因为Fu3的m2方法的形参列表是(int a, int b),//那么Zi3的m2方法的形参列表(int x, int y)//它们是重写关系,不看形参的名字,//只看类型,个数,顺序public void m2(int x, int y){System.out.println("Zi.m2");}//因为Fu3的m3方法的形参列表是(int a, int b),//那么Zi3的m3方法的形参列表(int x)//它们是重载关系,不看形参的名字,//只看类型,个数,顺序public void m3(int x){System.out.println("Zi.m3");}
}

1.4.2 @Override有什么用

@Override是一个注解。是对代码进行注释。这个注释是可以给编译器看的,
编译器看到某个方法上面加了@Override,就会对这个方法按照重写的要求,
进行格式检查,看他是否满足重写的要求,不满足就编译报错,如果满足就
不报编译错。
但是,如果一个重写的方法,没有违反重写的要求,那么加@Override
和不加它没有任何区别。

总结:@Override只是对重写方法起到一个格式检查的作用,不影响重写的本质。

建议:重写的方法都加上@Override。

1.5 super关键字

super可以调用父类声明的xxx成员。

1、super() 或 super(实参列表)

它们会出现在子类构造器的首行。表示调用父类的构造器。它只能找直接父类的。

  • super():找父类无参构造。

  • super(实参列表):找父类的有参构造。

示例代码
GrandFather爷爷类
package com.atguigu.keyword;public class GrandFather {//爷爷类private int a;public GrandFather() {System.out.println("GrandFather的构造器");}public GrandFather(int a) {this.a = a;}
}

 

Father父类
package com.atguigu.keyword;public class Father extends GrandFather{//父类public Father(){System.out.println("Father的构造");}
}

 

GrandSon孙子类

 


public class GrandSon extends Father{public GrandSon() {super();System.out.println("GrandSon的构造器");}public GrandSon(int a){
//        super(a);//报错,因为Father类没有有参构造}
}

测试类TestGrandSon

package com.atguigu.keyword;public class TestGrandSon {public static void main(String[] args) {GrandSon g = new GrandSon();/*从构造器的角度来说,孙子要先找爸爸,爸爸再找爷爷。但是不能孙子直接找爷爷的构造器。*/}
}

2、super.方法

当子类重写了父类的某个方法,但是在子类中又要调用父类被重写的方法,就必须用“super.被重写的方法”,否则就会自己调用自己的。

如果子类没有重写父类的某个方法,在子类中需要调用这个父类的方法,加不加super.都可以。

3、super.成员变量

super.成员变量是表示使用父类的成员变量。

当父类的成员变量,与子类的成员变量重名了,可以用"super.成员变量"表示使用父类的成员变量。

如果父类的成员变量,与子类的成员变量没有重名问题,可以直接使用父类的成员变量。

虽然我们讲了这种使用方式,但是开发中一定要避免父子类的成员变量重名。

示例代码

父类Fu

package com.atguigu.keyword;public class Fu {public int a = 1;public  int b = 1;
}

 

子类Zi

package com.atguigu.keyword;public class Zi extends Fu{public int a = 2;public void test(int a){System.out.println("a = " + a);//有重名问题,就近原则,使用局部变量System.out.println("this.a = " + this.a);//有重名问题,明确说明使用本类的System.out.println("super.a = " + super.a);//有重名问题,明确说明使用父类的System.out.println("b = " + b);//没有重名问题,直接使用父类的}
}

 

测试类TestZi

package com.atguigu.keyword;public class TestZi {public static void main(String[] args) {Zi z = new Zi();z.test(3);}
}

4、注意

无论在子类中调用父类的构造器,还是父类的方法,还是父类的成员变量,都要求被调用的父类成员不能是private。就算加super也不能调用。

1.6 根父类Object类

1.6.1 根父类的概念

java.lang.Object类是所有Java类的父类,它是老祖宗。所有Java类都是它的子类。

如果一个类没有明确说明它继承(extends)哪个类,那么它的父类就是Object。

1.6.2 toString方法

Object类中声明了public String toString()方法,所有Java类(或者说所有引用数据类型)都会从Object继承这个方法。

如果子类不重写toString方法,默认返回的是 对象的实际类型(new它的类型) @ 对象的hashCode值的十六进制形式。

官方API文档说明了,建议所有子类都重写toString方法,用于返回对象的详细信息,一般都是返回对象的属性值拼接。等价于我们之前做练习用的getInfo方法。

package com.atguigu.api;//Person的直接父类就是Object
public class Person {
}

 

package com.atguigu.api;public class TestPerson {public static void main(String[] args) {Person p = new Person();System.out.println(p.toString());//这里toString方法,就是从Object类继承的//默认打印的是 com.atguigu.api.Person@4eec7777System.out.println(p.hashCode());//1324119927//1324119927是p对象的hash值的十进制形式//4eec7777是 hash值的十六进制形式//关于hash值是什么,干什么用的,今天先不讨论,等后面讲哈希表等数据结构的时候再说。}
}

toString()非常特殊,当我们用System.out.println() 或 System.out.print()方法打印对象时,默认就会调用这个对象的toString,不用程序员手动调用。或者当我们把一个Java对象与字符串进行拼接时,也会自动调用这个对象的toString。

toString()方法的重写有两个快捷键: 

  • Alt + Insert:属性拼接的模板

  • @Override
    public String toString() {return "Rectangle{" +"length=" + length +", width=" + width +'}';
    }

  • Ctrl + O:重写父类的哪些方法。使用调用父类toString方法的模板。

@Override
public String toString() {return super.toString();
}

1.6.3 示例代码1

Rectangle矩形类
package com.atguigu.api;public class Rectangle {private double length;private double width;public Rectangle() {}public Rectangle(double length, double width) {this.length = length;this.width = width;}public double getLength() {return length;}public void setLength(double length) {this.length = length;}public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}//下面的toString方法,使用快捷键Alt + Insert自动生成@Overridepublic String toString() { return "Rectangle{" +"length=" + length +", width=" + width +'}';}
}

测试类
package com.atguigu.api;public class TestRectangle {public static void main(String[] args) {Rectangle r = new Rectangle(8,4);System.out.println(r.toString());System.out.println(r);//打印r对象时,自动会调用r的toString}
}

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

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

相关文章

【图像分割】光流生成标签(matlab)

文章目录 1. 框架2. opticalFlow_label3. 光流 1. 框架 2. opticalFlow_label close all; clear; clc; % 使用光流进行标签的生成 %% 视频帧的读取 npy_data readNPY(train.npy);%% 提取标签的坐标 first_label squeeze(npy_data(2,1,:,:)); h fspecial("gaussian&quo…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中&#xff0c;WITH 子句提供了一种编写辅助语句的方法&#xff0c;以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单&#xff0c;便于阅读。这些语句通常称为通用表表达式&#xff08;Common Table Express…

快速了解开发过程中VO、DTO、BO、 DO、PO、POJO、Entity的概念、区别、作用

​ 目录 ​前言 VO&#xff08;Value Object&#xff0c;值对象&#xff09; DTO&#xff08;Data Transfer Object&#xff0c;数据传输对象&#xff09; BO&#xff08;Business Object&#xff0c;业务对象&#xff09; DO&#xff08;Data Object&#xff0c;数据对象…

OpenCV从入门到精通实战(六)——多目标追踪

基于原生的追踪 使用OpenCV库实现基于视频的对象追踪。通过以下步骤和Python代码&#xff0c;您将能够选择不同的追踪器&#xff0c;并对视频中的对象进行实时追踪。 步骤 1: 导入必要的库 首先&#xff0c;我们需要导入一些必要的Python库&#xff0c;包括argparse、time、…

三级等保安全解决方案——实施方案

实施方案设计 本方案将依照国家有关信息安全建设的一系列法规和政策&#xff0c;为电台建立体系完整、安全功能强健、系统性能优良的网络安全系统。以“统一规划、重点明确、合理建设、逐步强化”为基本指导原则。根据电台网络系统不同信息的重要性调整保护策略&#xff0c;不欠…

SpringBoot项目创建,详细流程

一、前言 Spring Boot是一个开源的Java框架&#xff0c;由Pivotal团队&#xff08;现为VMware旗下&#xff09;开发&#xff0c;通过提供默认配置和一系列启动器&#xff08;starters&#xff09;来简化项目配置&#xff0c;使得开发者能够快速启动和运行Spring应用程序。 ‍ …

K8s 部署 elasticsearch-7.14.0 集群 及 kibana 客户端

一、K8s 部署 elasticsearch-7.14.0 集群 安装规划 组件replicas类型es3StatefulSetkibana1Deployment 使用 k8s 版本为&#xff1a;v1.18.0 。 本次使用 OpenEBS 来作为存储引擎&#xff0c;OpenEBS 是一个开源的、可扩展的存储平台&#xff0c;它提供了一种简单的方式来创…

国内首款千亿参数MoE模型APUS-xDAN-4.0:性能逼近GPT-4,可在4090显卡上运行

前言 随着人工智能技术的快速发展&#xff0c;模型参数的数量已成为衡量其复杂性和处理能力的重要指标。近日&#xff0c;国内科技企业APUS与AI创企新旦智能联合宣布&#xff0c;成功开源了国内首个千亿参数的混合专家模型&#xff08;MoE&#xff09;&#xff0c;APUS-xDAN-4…

锁策略和死锁问题

锁策略 乐观锁 vs 悲观锁重量级锁 vs 轻量级锁自旋锁 vs 挂起等待锁读写锁 vs 互斥锁公平锁 vs 非公平锁可重入锁 vs 不可重入锁死锁死锁产生的必要条件如何简单的解决死锁问题 小结 这里不是描述的某个特定锁,而是描述的锁的特性,描述的是"一类锁". 乐观锁 vs 悲观…

Java配置环境变量的过程

第一步&#xff1a;先找到你下载java的文件夹。 第二步&#xff1a;点击它进入看到新的文件夹继续点击。 第三步&#xff1a;点击bin文件。 第四步&#xff1a;点进去bin文件之后复制上述文件的地址。 第五步&#xff1a;回到你的电脑位置右键鼠标点击空白位置出现属性点进去 第…

设计模式胡咧咧之策略工厂实现导入导出

策略模式&#xff08;Strategy Pattern&#xff09; 定义&#xff1a; 定义了一组算法&#xff0c;将每个算法都封装起来&#xff0c;并且使它们之间可以互换。 本质: 分离算法&#xff0c;选择实现 应用场景 何时使用 一个系统有许多类&#xff0c;而区分他们的只是他们直接…

复合机器人在磁钢上下料中的应用及其优势分析

复合机器人是一种集成了移动机器人和工业机器人功能的设备&#xff0c;其独特之处在于拥有“手、脚、眼、脑”的综合能力&#xff0c;从而实现了更高的灵活性和操作效率。在磁钢上下料的应用场景中&#xff0c;复合机器人能够发挥显著的优势。 首先&#xff0c;复合机器人可以根…

Photomator 3.3.5 (macOS Universal) - 照片编辑软件

Photomator 3.3.5 (macOS Universal) - 照片编辑软件 适用于 Mac、iPhone 和 iPad 的终极照片编辑器 请访问原文链接&#xff1a;https://sysin.org/blog/photomator/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Photomat…

计算机网络 -- 网络编程基础

一 学习准备 1.1 IP地址 在 前文中我们提到过: IP 是全球网络的基础&#xff0c;使用 IP 地址来标识公网环境下主机的唯一性&#xff0c;我们可以根据 目的IP地址 进行跨路由器的远端通信。 但是我们也提到了&#xff0c;通过 IP 地址&#xff0c;只能寻找到目标主机&#xff…

视频质量度量VQM算法详细介绍

视频质量评价 视频质量评价(Video Quality Assessment,VQA)是指通过主观、客观的方式对视频图像的内容、画质等,进行感知、衡量与评价。 ITU definations subjective assessment: the determination of the quality or impairment of programme-like pictures presented…

【代码随想录】【动态规划】day48:打家劫舍

打家劫舍1 def rob(self, nums):""":type nums: List[int]:rtype: int"""# 分为两个情况&#xff0c;偷还是不偷&#xff0c;# dp[i]为考虑到第i个房间时的最大值if len(nums) 0: # 如果没有房屋&#xff0c;返回0return 0if len(nums) 1: #…

【 书生·浦语大模型实战营】作业(五):LMDeploy 量化部署

【 书生浦语大模型实战营】作业&#xff08;五&#xff09;&#xff1a;LMDeploy 量化部署 &#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系…

Linux debian gdb dump

1.开发背景 记录 debian 下应用程序崩溃调试方法 2.开发需求 程序越界可以定位到越界的位置附近 3.开发环境 debian 操作系统&#xff0c;如果不支持需要查看是否存在对应的可执行文件 4.实现步骤 4.1 设置 dump 输出大小 ulimit -c unlimited # 设置输出大小 生成core 文…

【QT+OpenCV】车牌号检测 学习记录 遇到的问题

【QTOpenCV】车牌号检测 学习记录 首先在QT里面配置好OpenCV .pro文件中加入&#xff1a; INCLUDEPATH G:/opencv/build/include LIBS -L"G:/opencv/build/x64/vc14/lib"\-lopencv_core \-lopencv_imgproc \-lopencv_highgui \-lopencv_ml \-lopencv_video \-lo.c…

Linux下SPI设备驱动实验:使用内核提供的读写SPI设备中的数据的函数

一. 简介 前面文章的学习&#xff0c;已经实现了 读写SPI设备中数据的功能。文章如下&#xff1a; Linux下SPI设备驱动实验&#xff1a;验证读写SPI设备中数据的函数功能-CSDN博客 本文来使用内核提供的读写SPI设备中的数据的API函数&#xff0c;来实现读写SPI设备中数据。 …