OOP 设计模式:接口与类的封装和重写(override)以及重载(overload)

2024-03-25 06:58

本文主要是介绍OOP 设计模式:接口与类的封装和重写(override)以及重载(overload),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

要点

  • 子类是 extends 父类出来的

  • 子类会集成父类所有 public 类型的实例变量和方法,但不会集成父类所有 private 类型的变量和方法

  • 继承下来的属性可以被覆盖掉,但实例变量不能被覆盖掉

  • 类的多态性可以从方法override 和 overload 来体现

  • 一个类可以继承另外一个类或者实现多个接口


 

重写 Override

工程意义:重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

如果需要扩展行为,就可以通过子类来实现,因此,继承是给类扩展和添加行为时的唯一工具。从继承开始说起。

type Rect = {x: number,y: number
}class Animal {protected flegCount:number;protected isAlive:boolean;protected color:string;protected position: Rect;constructor(){this.flegCount = 4;this.isAlive = true;this.color = "white"this.position = {x: 0,y: 0}}speak():string|null {return null;}
}class Dog extends Animal {speak():string|null {return "旺旺旺!";}
}class Cat extends Animal {speak():string|null {return "喵喵喵!";}
}

发生重写 Override - Animal 类 和 Cat 类中的 speak 方法的方法名和参数都一样

上面的 TypeScript 代码片段是一个基础的继承示例。Dog 和 Cat 类继承自 Animal,这意味着它们拥有 Animal 所有的属性和方法,我们不需要重新去定义它们,除非我们想覆盖原来的实现,就像上面的例子一样。继承允许我们将公共行为、状态(方法和属性)抽象到一个单独的地方,我们可以从那里(父类)提取。

const d1 = new Dog();
const c1 = new Cat();console.log(d1.speak());
console.log(c1.speak());

在线地址

继承的另一大好处是用父类的类型声明的变量也可以兼容来自子类的对象,主要体现在 Java,TypeScript 等强类型语言。比如:

let animals:Animal[] = [new Cat(), new Dog()]
animals.forEach( a => console.log(a.speak()));

在线地址

紧接着之前定义的类,这个例子声明了一组 Animal 类型的元素,包含了一个 Cat 和 一个 Dog。这是可行的,因为两个对象有相同的父类。同样,我们可以在安全地调用 speak 方法。因为这个方法已经在父类中定义了,我们知道所有的对象都有它。

重载 Overload

工程意义: 重载允许一个函数接受不同数量或类型的参数时,作出不同的处理

因为重载方法不是用来满足定义在父类(发生继承场景)的多态,所以重载的方法比较有扩展性。

class Overloads {uniqueID: number | string | null;constructor() {this.uniqueID = null;}addNums(a: string, b: string);addNums(a: number, b: number);addNums(a: string, b: number);addNums(a: number, b: string);addNums(a: number|string, b: number| string): number {if (typeof a === 'string') {a = Number(a);} if (typeof b === 'string') {b = Number(b);} return a + b;}setUniqueID(theID: string);setUniqueID(ssNumber: number) setUniqueID(value: number|string) {if (typeof value === 'number') {this.uniqueID = value} else if (typeof value === 'string') {const numberString = value + "";this.uniqueID = value}}}

发生重载 Overload - Overloads的同一个类中的多个 addNums 方法名相同,参数不同

执行测试

const o = new Overloads();
console.log('------- example1 ------')
console.log(o.addNums(1, 2));
console.log(o.addNums('3','5'));console.log('------- example2 ------')
console.log(o.setUniqueID('1'));
console.log(o.uniqueID)console.log(o.setUniqueID(2));
console.log(o.uniqueID)

在线地址

在 Java 中是这样子的

public class Overloads {String uniqueID;public int addNums(int a, int b) {return a + b;}public double addNums(double a, double b) {return a + b;}public void setUniqueID(String theID) {uniqueID = theID}public void setUniqueID(int ssNumber) {String numString = "" + ssNumber;setUniqueID(numString)}
}


 

重写与重载的区别

区别点

重载Overload方法

重写Overwrite方法

参数列表

必须修改

一定不能修改

返回类型

可以修改

一定不能修改

访问权限

可以修改

一定不能做更严格的限制

(可以降低限制,比如 protected 修改 public)


方法的重写(Overriding)和重载(Overloading)是面向对象中多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。

  • (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。

  • (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。

  • (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

更严厉的权限描述

type Rect = {x: number,y: number
}class Animal {protected flegCount:number;protected isAlive:boolean;protected color:string;protected position: Rect;constructor(){this.flegCount = 4;this.isAlive = true;this.color = "white"this.position = {x: 0,y: 0}}public speak():string|null {return null;}
}class Dog extends Animal {speak():string|null {return "旺旺旺!";}
}class PrivateDog extends Animal {//Class 'PrivateDog' incorrectly extends base class 'Animal'.//Property 'speak' is protected in type 'PrivateDog' but public in type 'Animal'.protected speak():string|null {return "严厉的旺旺旺!";}
}const d = new Dog();
console.log(d.speak())

在线地址

抽象类 Abstract Class

工程意义:因为抽象类不能实例化对象,所以必须要有子类来实现它之后才能使用。这样就可以把一些具有相同属性和方法的组件进行抽象,这样更有利于代码和程序的维护

abstract class Department {constructor(public name: string) {}printName(): void {console.log('Department name: ' + this.name);}abstract printMeeting(): void; // 必须在派生类中实现
}class AccountingDepartment extends Department {constructor() {super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()}printMeeting(): void {console.log('The Accounting Department meets each Monday at 10am.');}generateReports(): void {console.log('Generating accounting reports...');}
}let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在

在线地址

什么时候用类或者接口

  1. 抽象类适合用来定义某个领域的固有属性,也就是本质,接口适合用来定义某个领域的扩展功能。

  2. 当需要为一些类提供公共的实现代码时,应优先考虑抽象类。因为抽象类中的非抽象方法可以被子类继承下来,使实现功能的代码更简单。

  3. 当注重代码的扩展性跟可维护性时,应当优先采用接口。

    1. ①接口与实现它的类之间可以不存在任何层次关系,接口可以实现毫不相关类的相同行为,比抽象类的使用更加方便灵活;

    2. ②接口只关心对象之间的交互的方法,而不关心对象所对应的具体类。接口是程序之间的一个协议,比抽象类的使用更安全、清晰。一般使用接口的情况更多。

案例1 接口:植物园内的水果,可以被拆下来,并且未来可以做成果汁

  

案例2 抽象类:狗狗可以有很多品种

 

 

案例3 接口:交通工具

 

案例4 抽象类:企业雇佣的员工分类(小时工,周薪员工等员工)

 

附录

  • 《Head First Java》 Head first java chapter 7 继承与多态_dengmu1918的博客-CSDN博客

  • 接口与抽象类的区别 深入理解Java的接口和抽象类 - Matrix海子 - 博客园

  • 何时使用接口(抽象类)? - dashuai的博客 - 博客园

这篇关于OOP 设计模式:接口与类的封装和重写(override)以及重载(overload)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

Nginx 重写与重定向配置方法

《Nginx重写与重定向配置方法》Nginx重写与重定向区别:重写修改路径(客户端无感知),重定向跳转新URL(客户端感知),try_files检查文件/目录存在性,return301直接返回永久重... 目录一.try_files指令二.return指令三.rewrite指令区分重写与重定向重写: 请求

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP

Java中的Closeable接口及常见问题

《Java中的Closeable接口及常见问题》Closeable是Java中的一个标记接口,用于表示可以被关闭的对象,它定义了一个标准的方法来释放对象占用的系统资源,下面给大家介绍Java中的Clo... 目录1. Closeable接口概述2. 主要用途3. 实现类4. 使用方法5. 实现自定义Clos