继承,super,重写,多态,抽象,接口
继承,super,重写,多态,抽象,接口
继承
extends用于表示两个类之间的继承关系,继承是OOP的四大特性之一,他允许一个类(称之为子类或派送类) 继承另一个类(称之为父类或基类)的变量和方法,子类可以复用父类的方法和变量,也可以添加和覆盖父类的方法和变量
extends的基本语法
- 使用
extends关键字来声明子类继承父类
class ParentClass()
{
//父类属性和方法
}
class ChildrenClass extends ParentClass()
{
//子类的属性与方法
}
- 上述ChildrenClass类继承了ParentClass类,子类可以复用ParentsClass类的属性与方法
继承的特性
- 代码复用:子类可以之间使用父类的方法和属性,无需重新编写
- 扩展性:子类可以添加新的属性和方法,以满足实际开发需求
- 多态性:通过继承子类可以覆盖父类的方法,实现多态性
继承的限制
- java中不支持多继承,即一个类只能有一个父类.但后续学的接口是可以多继承的.
- 再java中所有类都直接或间接的继承Object类
继承的层级结构
- 由于继承的限制性,即一个子类只能继承一个父类,但一个父类可以被多个子类继承,子类也可以作为其他子类的父类.再java中就形成了一个树状层级结构,
继承下构造器的调用
- 在创建子类时,java会优先调用父类的构造器(如果没有显式调用,则会调用无参构造器),然后再调用子类的构造器,.如果需要显式调用,则需用
super关键字来实现
class ParentClass
{
public ParentClass()
{
System.out.println("这是父类的无参构造方法");
}
public ParentClass(String str)
{
System.out.println("这是父类的一个带参构造器");
}
}
class ChildrenClass extends ParentClass{
public ChildrenClass()
{
System.out.println("这是子类的无参构造方法");
}
public ChildrenClass(String str){
System.out.println("这是一个子类的带参构造器");
}
public static void main(String[] args) {
ChildrenClass childrendclass = new ChildrenClass();
ChildrenClass childrenclass new ChildrenClass("11");
}
}

- 分析:
ChildrenClass继承了ParentClass接着再main函数创建ChildrenClass的无参实例对象时,会先调用父类的无参构造器打印这是父类的无参构造方法,接着再调用子类的无参构造器这是子类的无参构造方法
当实例化子类带参构造器时,也会先调用父类的带参构造器这是父类的无参构造方法,接着调用子类的带参构造器这是一个子类的带参构造器
- 当子类构造器调用了父类的有参方法,则父类的无参构造器不会被调用,只会调用有参构造器
调用了无参构造器构造器,则父类的有参构造器不会被调用, 即每次只会调用一种构造器
super关键字
super关键字是java中重要的一个引用变量,他主要用于引用当前对象的父类对象,super()实际是调用父类的构造器
调用父类构造函数
- 在子类的构造器中,你可以使用
super()调用父类的构造函数,
访问父类中的成员变量
- 若子类想要调用父类的成员变量时可以用
super关键字进行调用
class Parent {
int value = 100;
}
class Child extends Parent {
int value = 200;
void display() {
System.out.println("Parent value: " + super.value); //调用父类的value
System.out.println("Child value: " + this.value);
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.display();
}
}
访问父类的方法
在子类中可以使用super关键字子访问父类的方法
class Parent {
void display() {
System.out.println("Parent display method");
}
}
class Child extends Parent {
@Override
void display() {
super.display(); // 调用父类的display方法
System.out.println("Child display method");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.display();
}
}
重写(Override
override:也称覆盖,重写是子类对父类非静态,非private,非final方法的实现过程进行重新编写, 返回值(JDK7之后,被重写的方法返回值,类型可以不同,但必须有父子关系)和形参都不能改变.即外壳不能改变→重写的核心
方法名与参数列表必须相同
子类中的重写方法必须与父类中的被重写方法具有相同的方法名和参数列表,相同的参数列表即意味着,参数类型,数量,顺序都必须相同
返回类型
- 如果父类被重写的方法放回的是基本数据类型或
void,则子类重写的方法的返回值必须与父类方法一直 - 如果父类被重写方法放回的是引用数据类型,则子类重写的方法返回值的类型可以与父类相同或者是其子类型
public class Animal {
// ... 其他方法 ...
public Animal getAnimal() {
return new Animal(); // 返回一个Animal对象
}
}
public class Dog extends Animal {
// ... 其他方法 ...
// 重写getAnimal方法,但返回更具体的类型Dog
@Override
public Dog getAnimal() {
return new Dog(); // 返回一个Dog对象,它是Animal的子类 也是合法的
}
}
访问权限(封装
- 子类重写方法的权限(
public,protected,默认,private)都不能低于父类方法的访问权限,例如父类中方法是public,则子类中必须是public
异常处理
- 子类重写方法抛出的异常类型,应该是父类被重写方法抛出的异常的子集或者相同,即子类不能抛出比父类多的异常
静态方法不能被重写
- 静态方法只与类相关,并非与实例相关,.静态方法不属于继承的层次结构.
final方法不能被重写
被final修饰的方法表示该方法不能被覆盖或继承,因此子类不能重写父类中的final方法
多态
严格的文字定义:它允许我们使用父类类型变量来引用子类对象这意味着,当我们对父类类型的变量进行操作时,具体的行为取决于该变量所引用的实际对象的类型
简单的理解:同一个行为具有不同的表现形式,即执行一段代码java在运行中能根据对象产生不同的结果
多态的前提条件
- 子类继承同一父类
- 子类覆盖(重写)父类方法
- 父类引用指向子类对象
- 注意点:多态下,引用调用的方法是子类重写方法,调用的属性是父类的属性
抽象类 (abstract
抽象类也是类,只是具备了一些特殊的性质;抽象类的主要作用是提供了一个模板或是框架,这个模板中定义了一些属性与方法,但是并不需要完全实现这些方法.→相当于你告诉其他类:你们可以按照我的这个模板来创建自己的类,但是你需要实现我未完成的部分;
模板作用
- 想象你有一个抽象类叫做
Animal,它有一个方法eat()。但不同的动物吃东西的方式可能不同,所以eat()方法没有具体的实现。其他类,比如Dog和Cat,可以继承Animal类,然后各自实现自己的eat()方法.
强制子类实现某个方法
- 如果你有一个抽象方法(即在抽象类中声明但没有实现的方法),那么任何继承这个抽象类的子类都必须实现这个方法。这确保了子类具有某种特定的功能或行为
代码复用
- 抽象类可以包含一些通用的、非抽象的方法和属性,这些方法和属性可以被所有子类共享,避免了在每个子类中重复编写相同的代码
定义了接口
- 虽然接口(Interface)也用于定义类的行为,但抽象类可以包含方法的实现,而接口只能定义方法签名。因此,在某些情况下,抽象类可以提供更灵活的接口定义。
注意点
- 抽象类不能被实例化
- 这是
abstract类最基本的特点。由于抽象类可能包含没有具体实现的抽象方法,因此不能创建抽象类的实例。只能创建抽象类的非抽象子类的实例
- 抽象类中可以包含抽象方法和非抽象方法
- 有抽象方法的类一定是抽象类,但抽象类不一定有抽象方法。即使抽象类中可以没有抽象方法,普通类中不能有抽象方法
- 子类必须实现父类中的所有抽象方法
- 如果一个类继承了抽象类,并且该抽象类中有抽象方法,那么子类必须提供这些方法的具体实现,除非子类也是抽象类
- 抽象方法不能有方法体
- 被
abstract修饰的方法不能有具体的方法体,即没有大括号{}和具体的实现代码
- 不能与
private、static、final等关键字共用
private修饰的方法表示私有,不允许子类访问,而abstract修饰的方法必须被子类覆盖重写才能使用,所以二者矛盾。static关键字修饰的是静态方法,静态方法属于类而不属于实例→属于类,而抽象方法没有具体的实现,需要子类来提供,所以抽象方法不能是静态的。final关键字表示最终的,不可改变的,而抽象方法需要子类来实现,所以不能是final的。
- 抽象类必须有构造方法
- 虽然抽象类不能被实例化,但它的构造方法可以用于被子类调用。子类在创建对象时,会先调用父类的构造方法
// 抽象类 Animal
abstract class Animal {
// 抽象方法
abstract void makeSound();
// 非抽象方法
void eat() {
System.out.println("The animal eats.");
}
// 构造方法
Animal() {
System.out.println("Animal is being constructed.");
}
}
// Dog 类继承自 Animal
class Dog extends Animal {
// 实现从 Animal 继承的抽象方法
@Override
void makeSound() {
System.out.println("The dog barks.");
}
// Dog 类的构造方法
Dog() {
super(); // 调用父类的构造方法
System.out.println("Dog is being constructed.");
}
}
// 主类
public class Main {
public static void main(String[] args) {
// 抽象类不能被实例化
// Animal animal = new Animal(); // 这是错误的
// 创建 Dog 和 Cat 的对象
Dog dog = new Dog();
Cat cat = new Cat();
// 调用方法
dog.eat();
dog.makeSound();
}
}
- 结果如下
Animal is being constructed. //父类无参构造器先被调用
Dog is being constructed.
The animal eats.
The dog barks.
接口
接口声明了一组方法(规范),但不关心这些方法(规范)是怎么实现的,任何实现这些接口的类都必须遵循这些方法(规范),但对于具体方法的细节完全由类自身决定.
接口可以看作是一种特殊的类,但接口中所有的方法都是抽象方法(即没有方法体),通常不会写属性;所有的属性都是常量(即使用
public static final修饰
接口的特性
1.抽象性
- 接口中的所有方法都是抽象的,或者说都被隐型定义成abstract;的因此它们没有方法体。实现接口的类必须为接口中的所有方法提供具体的实现
2.接口不能被实例化
- 接口本身不能被实例化,即不能使用
new关键字来创建接口的实例。但是,可以声明接口的引用变量,该变量引用实现该接口的类的实例。
3.接口可以多实现
- 一个类可以实现多个接口,通过逗号分隔接口名。这允许类继承多个接口中的方法规范
public class Dog implements Animal, Runnable { //多实现接口
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping");
}
@Override
public void run() {
System.out.println("Dog is running");
}
}
4.多继承的替代
- 在Java中,类只能继承自一个父类,但可以实现多个接口。这提供了一种替代多重继承的方式,允许类继承多个行为。
5.接口的继承
- 接口可以继承自其他接口,通过
extends关键字实现。这允许接口之间共享方法的规范
// 定义一个父接口
interface ParentInterface {
void method1();
void method2();
int CONSTANT = 10; // 可以在接口中定义常量
}
// 定义一个子接口,继承自ParentInterface
interface ChildInterface extends ParentInterface {
void method3();
}
- 在这个例子中,
ChildInterface继承自ParentInterface,因此它自动包含了ParentInterface中定义的所有方法(method1()和method2())和常量(CONSTANT)。同时,ChildInterface还可以定义自己特有的方法(如method3())。
接口的作用
- 多继承
- 不同子类实现相同的行为
JDK1.8之后(包括1.8)接口的变化
- 可以在接口写非抽象方法
// 使用接口名.方法名调用
static void 方法名称() {
}
// 可以被子类继承,实例化子类之后调用
default void 方法名称() {
}
接口与抽象类的区别
实现与继承
- 接口:一个类可以实现多个接口,通过
implements关键字实现,接口中所有的方法都是抽象的,即没有方法体 - 抽象类: 一个类只能继承一个抽象类,沟通
extends关键字实现,抽象类中可以包含抽象方法和非抽象方法
使用场景
- 接口: 通常用于定义一种规范或契约,不关心对象的具体实现.如定义API,插件架构等
- 抽象类: 常用于提供一个公共父类,包含一些公共的方法和属性,有子类继承并实现具体的方法.
设计原则
- 接口:强调“契约”和“规范”,关注对象的行为。一个类可以实现多个接口,从而具备多种能力
- 抽象类:强调模板与复用,通过继承实现代码的复用,子类继承抽象类后,可以直接使用父类中的非抽象方法和属性。
实例化
- 接口:接口不能被实例化,只能被实现
- 抽象类:可以被实例化,但只能通过子类被实例化,如果抽象方法中包括非抽象方法则子类可以直接调用.
继承,super,重写,多态,抽象,接口的更多相关文章
- java面向对象3-继承(继承、抽象类、抽象接口)
4.继承 面向对象概念-类与对象的关系 封装:指隐藏对象的属性和实现细节,仅对外提供公共访问方式,private-构造方法/构造器-this关键字-static关键字(javadoc制作工具类) -代 ...
- JAVA 之 多态 抽象 接口
一:多态 1:多态 一个对象有多种形式的能力 2:步骤 1编写父类派生子类 2子类重写父类方法 3用父类的数据类型引用子类对象 3:静态多态的实现方式就是方法重载 4:动态多态的实现方式就是重写 ...
- Three---面向对象与面向过程/属性和变量/关于self/一些魔法方法的使用/继承/super方法/多态
python的面向对象 面向对象与面向过程 面向过程 面向过程思想:需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做) 面向对象 面向对象的三 ...
- 继承(extends), 多态 , 抽象(abstract)接口() 易混难点解析
特性 java是单继承的,一个类直接继承的父类只能有唯一的一个 java中父类可以有多个子类 Object是所有类的父类,一个类没有父类则默认继承Object; 继承中的重写 子类重写方法访问权限不能 ...
- Java中关于继承、类、多态、接口的知识点
继承 含义:在面向对象编程中,可以通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类 优点:1)代码的重用性:2)子类扩展父类的属性和方法:3)父类的属性和方法可用于子类:4)设计应用程序 ...
- java四大特性理解(封装继承多态抽象)
封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对象,这些对象通过一个受保护的接口访问其他对象.封装是一 ...
- Java开发知识之Java的继承多态跟接口*
Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...
- Java知识回顾 (7) 继承、多态与接口、封装
一.继承 1.1 继承的特性 子类拥有父类非 private 的属性.方法. 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展. 子类可以用自己的方式实现父类的方法. Java 的继承是单继承, ...
- PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)
前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...
- java中封装,继承,多态,接口学习总结
### 一:封装java中封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问.要访问该类的代码和数据,必须通 ...
随机推荐
- 重新整理.net core 计1400篇[六] (.net core 一个简易版的依赖注入容器 )
前言 我们了解到一个依赖注入的形式是: 注入依赖服务:var root = new Cat().Register<IFoo, Foo>(Lifetime.Transient); 获取对应的 ...
- Vue权限管理该怎么做?控制到按钮级别的权限怎么做?
一.是什么 权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源 而前端权限归根结底是请求的发起权,请求的发起可能有下面两种形式触发 页面加载触发 页面上的按钮点击触发 总的 ...
- Redis持久化技术浅析
Redis是一种内存数据库,数据都存储在内存中,因此可以快速地直接基于内存中的数据结构进行高性能的操作,但是所有数据都在内存中,一旦服务器宕机,内存中的数据就会全部丢失,数据将无法恢复,因此Redis ...
- HarmonyOS NEXT应用开发案例——自定义TabBar
介绍 本示例主要介绍了TabBar中间页面如何实现有一圈圆弧外轮廓以及TabBar页签被点击之后会改变图标显示,并有一小段动画效果. 效果图预览 使用说明: 依次点击tabBar页面,除了社区图标之外 ...
- 说说关系型数据库与Serverless
简介: 看到如今Serverless在云计算行业喷薄欲出的态势,像极了<星星之火,可以燎原>中的描述:虽然不能预测未来的发展和变化,但对于云计算来说这是个相对确定的方向.本文从产业界和学术 ...
- 浅谈分布式一致性:Raft 与 SOFAJRaft
简介: SOFAJRaft已开源 作者 | 家纯来源 | 阿里技术公众号 一 分布式共识算法 (Consensus Algorithm) 1 如何理解分布式共识? 多个参与者针对某一件事达成完全一致: ...
- WPF 笔迹触摸点收集工具
本文来安利大家一个工具,可以用来收集笔迹的触摸点,这个工具完全开源 在开始之前先看一下工具的界面 实现方式其实就在触摸的时候收集触摸点信息,上面的工具有很多功能都没有实现的.笔迹绘制的功能使用 WPF ...
- Vue源码-手写mustache源码
引言 在Vue中使用模板语法能够非常方便的将数据绑定到视图中,使得在开发中可以更好的聚焦到业务逻辑的开发. mustache是一个很经典且优秀的模板引擎,vue中的模板引擎也对其有参考借鉴,了解它能更 ...
- 开源相机管理库Aravis例程学习(四)——multiple-acquisition-signal
目录 简介 例程代码 函数说明 g_main_loop_new g_main_loop_run g_main_loop_quit g_signal_connect arv_stream_set_emi ...
- 利用MOS管构成基本的数字逻辑门
欢迎各位朋友关注"郝旭帅电子设计团队",本微信公众号会定时更新相关技术类资料.软件等等,希望各位朋友都能在本微信公众号获得一些自己想要的"东西". 非门原理图中 ...