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

相关文章

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果: 解密后的数据就是正常数据: 后端:使用的是spring-cloud框架,在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version></dependency> 编写一个AES加密

JavaSE——封装、继承和多态

1. 封装 1.1 概念      面向对象程序三大特性:封装、继承、多态 。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节 。     比如:对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器, USB 插孔等,让用户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU 、显卡、内存等一些硬件元件。

java线程深度解析(一)——java new 接口?匿名内部类给你答案

http://blog.csdn.net/daybreak1209/article/details/51305477 一、内部类 1、内部类初识 一般,一个类里主要包含类的方法和属性,但在Java中还提出在类中继续定义类(内部类)的概念。 内部类的定义:类的内部定义类 先来看一个实例 [html]  view plain copy pu

哈希表的封装和位图

文章目录 2 封装2.1 基础框架2.2 迭代器(1)2.3 迭代器(2) 3. 位图3.1 问题引入3.2 左移和右移?3.3 位图的实现3.4 位图的题目3.5 位图的应用 2 封装 2.1 基础框架 文章 有了前面map和set封装的经验,容易写出下面的代码 // UnorderedSet.h#pragma once#include "HashTable.h"

模拟实现vector中的常见接口

insert void insert(iterator pos, const T& x){if (_finish == _endofstorage){int n = pos - _start;size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;reserve(newcapacity);pos = _start + n;//防止迭代

封装MySQL操作时Where条件语句的组织

在对数据库进行封装的过程中,条件语句应该是相对难以处理的,毕竟条件语句太过于多样性。 条件语句大致分为以下几种: 1、单一条件,比如:where id = 1; 2、多个条件,相互间关系统一。比如:where id > 10 and age > 20 and score < 60; 3、多个条件,相互间关系不统一。比如:where (id > 10 OR age > 20) AND sco

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a

第二十四章 rust中的运算符重载

注意 本系列文章已升级、转移至我的自建站点中,本章原文为:rust中的运算符重载 目录 注意一、前言二、基本使用三、常用运算符四、通用约束 一、前言 C/C++中有运算符重载这一概念,它的目的是让即使含不相干的内容也能通过我们自定义的方法进行运算符操作运算。 比如字符串本身是不能相加的,但由于C++中的String重载了运算符+,所以我们就可以将两个字符串进行相加、但实际