继承,super,重写,多态,抽象,接口

继承

extends 用于表示两个类之间的继承关系,继承是OOP的四大特性之一,他允许一个类(称之为子类或派送类) 继承另一个类(称之为父类或基类)的变量和方法,子类可以复用父类的方法和变量,也可以添加和覆盖父类的方法和变量

extends的基本语法

  • 使用extends 关键字来声明子类继承父类
class ParentClass()
{
//父类属性和方法
} class ChildrenClass extends ParentClass()
{
//子类的属性与方法
}
  • 上述ChildrenClass类继承了ParentClass类,子类可以复用ParentsClass类的属性与方法

继承的特性

  1. 代码复用:子类可以之间使用父类的方法和属性,无需重新编写
  2. 扩展性:子类可以添加新的属性和方法,以满足实际开发需求
  3. 多态性:通过继承子类可以覆盖父类的方法,实现多态性

继承的限制

  • 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在运行中能根据对象产生不同的结果

多态的前提条件

  1. 子类继承同一父类
  2. 子类覆盖(重写)父类方法
  3. 父类引用指向子类对象
  • 注意点:多态下,引用调用的方法是子类重写方法,调用的属性是父类的属性

抽象类 (abstract

抽象类也是类,只是具备了一些特殊的性质;抽象类的主要作用是提供了一个模板或是框架,这个模板中定义了一些属性与方法,但是并不需要完全实现这些方法.→相当于你告诉其他类:你们可以按照我的这个模板来创建自己的类,但是你需要实现我未完成的部分;

模板作用

  • 想象你有一个抽象类叫做Animal,它有一个方法eat()。但不同的动物吃东西的方式可能不同,所以eat()方法没有具体的实现。其他类,比如DogCat,可以继承Animal类,然后各自实现自己的eat()方法.

强制子类实现某个方法

  • 如果你有一个抽象方法(即在抽象类中声明但没有实现的方法),那么任何继承这个抽象类的子类都必须实现这个方法。这确保了子类具有某种特定的功能或行为

代码复用

  • 抽象类可以包含一些通用的、非抽象的方法和属性,这些方法和属性可以被所有子类共享,避免了在每个子类中重复编写相同的代码

定义了接口

  • 虽然接口(Interface)也用于定义类的行为,但抽象类可以包含方法的实现,而接口只能定义方法签名。因此,在某些情况下,抽象类可以提供更灵活的接口定义。

注意点

  1. 抽象类不能被实例化
  • 这是abstract类最基本的特点。由于抽象类可能包含没有具体实现的抽象方法,因此不能创建抽象类的实例。只能创建抽象类的非抽象子类的实例
  1. 抽象类中可以包含抽象方法和非抽象方法
  • 有抽象方法的类一定是抽象类,但抽象类不一定有抽象方法。即使抽象类中可以没有抽象方法,普通类中不能有抽象方法
  1. 子类必须实现父类中的所有抽象方法
  • 如果一个类继承了抽象类,并且该抽象类中有抽象方法,那么子类必须提供这些方法的具体实现,除非子类也是抽象类
  1. 抽象方法不能有方法体
  • abstract修饰的方法不能有具体的方法体,即没有大括号{}和具体的实现代码
  1. 不能与privatestaticfinal等关键字共用
  • private修饰的方法表示私有,不允许子类访问,而abstract修饰的方法必须被子类覆盖重写才能使用,所以二者矛盾
  • static关键字修饰的是静态方法,静态方法属于类而不属于实例→属于类,而抽象方法没有具体的实现,需要子类来提供,所以抽象方法不能是静态的。
  • final关键字表示最终的,不可改变的,而抽象方法需要子类来实现,所以不能是final的。
  1. 抽象类必须有构造方法
  • 虽然抽象类不能被实例化,但它的构造方法可以用于被子类调用。子类在创建对象时,会先调用父类的构造方法
// 抽象类 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())。

接口的作用

  1. 多继承
  2. 不同子类实现相同的行为

JDK1.8之后(包括1.8)接口的变化

  • 可以在接口写非抽象方法
// 使用接口名.方法名调用
static void 方法名称() { }
// 可以被子类继承,实例化子类之后调用
default void 方法名称() {
}

接口与抽象类的区别

实现与继承

  • 接口:一个类可以实现多个接口,通过implements 关键字实现,接口中所有的方法都是抽象的,即没有方法体
  • 抽象类: 一个类只能继承一个抽象类,沟通extends 关键字实现,抽象类中可以包含抽象方法和非抽象方法

使用场景

  • 接口: 通常用于定义一种规范或契约,不关心对象的具体实现.如定义API,插件架构等
  • 抽象类: 常用于提供一个公共父类,包含一些公共的方法和属性,有子类继承并实现具体的方法.

设计原则

  • 接口:强调“契约”和“规范”,关注对象的行为。一个类可以实现多个接口,从而具备多种能力
  • 抽象类:强调模板复用,通过继承实现代码的复用,子类继承抽象类后,可以直接使用父类中的非抽象方法和属性。

实例化

  • 接口:接口不能被实例化,只能被实现
  • 抽象类:可以被实例化,但只能通过子类被实例化,如果抽象方法中包括非抽象方法则子类可以直接调用.

继承,super,重写,多态,抽象,接口的更多相关文章

  1. java面向对象3-继承(继承、抽象类、抽象接口)

    4.继承 面向对象概念-类与对象的关系 封装:指隐藏对象的属性和实现细节,仅对外提供公共访问方式,private-构造方法/构造器-this关键字-static关键字(javadoc制作工具类) -代 ...

  2. JAVA 之 多态 抽象 接口

    一:多态  1:多态   一个对象有多种形式的能力 2:步骤 1编写父类派生子类 2子类重写父类方法 3用父类的数据类型引用子类对象 3:静态多态的实现方式就是方法重载 4:动态多态的实现方式就是重写 ...

  3. Three---面向对象与面向过程/属性和变量/关于self/一些魔法方法的使用/继承/super方法/多态

    python的面向对象 面向对象与面向过程 面向过程 面向过程思想:需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做) 面向对象 面向对象的三 ...

  4. 继承(extends), 多态 , 抽象(abstract)接口() 易混难点解析

    特性 java是单继承的,一个类直接继承的父类只能有唯一的一个 java中父类可以有多个子类 Object是所有类的父类,一个类没有父类则默认继承Object; 继承中的重写 子类重写方法访问权限不能 ...

  5. Java中关于继承、类、多态、接口的知识点

    继承 含义:在面向对象编程中,可以通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类 优点:1)代码的重用性:2)子类扩展父类的属性和方法:3)父类的属性和方法可用于子类:4)设计应用程序 ...

  6. java四大特性理解(封装继承多态抽象)

    封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对象,这些对象通过一个受保护的接口访问其他对象.封装是一 ...

  7. Java开发知识之Java的继承多态跟接口*

    Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...

  8. Java知识回顾 (7) 继承、多态与接口、封装

    一.继承 1.1 继承的特性 子类拥有父类非 private 的属性.方法. 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展. 子类可以用自己的方式实现父类的方法. Java 的继承是单继承, ...

  9. PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)

    前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...

  10. java中封装,继承,多态,接口学习总结

    ### 一:封装java中封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问.要访问该类的代码和数据,必须通 ...

随机推荐

  1. c# 反编译对比(旧)

    前言 旧的都是我以前博客的迁移. 我们写代码有时候遇到一些问题,或者我们想优化我们的代码,我们想要看编译后的运行情况,那么反编译是必须要做的一件事. 正文 在此我自己使用的是reflector和ILS ...

  2. 错误 内存溢出 vendor/composer/autoload_real.php on line 66

    前言 首先声明我没怎么写过php,只是当时室友做php的时候跟他一起学了几分钟. 有时候部署一些php项目的时候,发生一些错误,但是百度一下五花八门的. 这个错误的完整版是: Fatal error: ...

  3. P7177 [COCI2014-2015#4] MRAVI 题解

    思路. 我们知道最初添加的液体越多,那么每个蚂蚁得到的液体也就越多,又因为标签里有深搜,所以可以用 DFS+二分解决(感觉说了一通废话),算是比较常规的一种解法了. 在此题中我们需要魔改一下建树,需在 ...

  4. 鸿蒙HarmonyOS实战-ArkUI动画(布局更新动画)

    前言 动画是一种通过连续展示一系列静止的图像(称为帧)来创造出运动效果的艺术形式.它可以以手绘.计算机生成或其他各种形式呈现.在动画中,每一帧都具有微小的变化,当这些帧被快速播放时,人眼会产生视觉上的 ...

  5. mac版本vscode窗口崩溃crashed

    1.截图 出现时机 当安装依赖的时候大概率会出现,甚至安装一次依赖会出现几次 解决 具体原因未知 重新启动电脑以及退出软件都不能解决 去官网重新下载,重新安装问题解决

  6. 力扣205(java)-同构字符串(简单)

    题目: 给定两个字符串 s 和 t ,判断它们是否是同构的. 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的. 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序 ...

  7. Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题

    简介: 从 Java Agent 报错开始,到 JVM 原理,到 glibc 线程安全,再到 pthread tls,逐步探究 Java Agent 诡异报错. 作者:鲁严波   从 Java Age ...

  8. 技术干货 | 深度解构 Android 应用面临紧急发版时的救星方案:mPaaS 热修复——DexPatch

    简介: 关于 Android 热修复方案--DexPatch 的介绍与使用说明 方案介绍 为了解决 Native 模块上线后的问题,mPaaS 提供了热修复功能,实现不发布客户端 apk 场景下的热修 ...

  9. [FE] uni-app 动态改变 navigationBarTitleText 导航标题

    改导航文字: uni.setNavigationBarTitle({ title: 'xx' }); 改 tabBar 文字: uni.setTabBarItem({ index: 0, text: ...

  10. WPF 获取全局所有窗口的创建显示事件 监控窗口打开

    本文将告诉大家如何在 WPF 里面进行全局监控任意的窗口创建显示打开,可以获取到每个 WPF 窗口的打开的时机.如此可以用来辅助定位问题和输出日志 这篇博客是有背景的,老司机告诉我说他的应用不响应鼠标 ...