TypeScript【类的继承、访问修饰符、readonly 修饰符、存取器、实例方法与静态方法、实例属性与静态属性、静态属性、抽象类】(三)-全面详解(学习总结---从入门到深化)

简介: TypeScript【类的继承、访问修饰符、readonly 修饰符、存取器、实例方法与静态方法、实例属性与静态属性、静态属性、抽象类】(三)-全面详解(学习总结---从入门到深化)

类的继承



在 TypeScript 里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式,是允许使用继承来扩展现有的类


继承示例

class Animal {
  move(distanceInMeters: number = 0) {
    console.log(`Animal moved ${distanceInMeters}m.`);
 }
}
class Dog extends Animal {
  bark() {
    console.log('Woof! Woof!');
 }
}
const dog = new Dog();
dog.bark();
dog.move(10);


Dog 继承了 Animal 的功能,因此我们可以创建一个 Dog 的实例,它能够 bark() move()

class Animal{
  public name:string;
  // 温馨提示:子类继承父类,父类存在构造函数,子类必须实现构造函数
  constructor(name:string){
    this.name = name;
 }
  move(distanceInMeters:number){
    console.log(`${this.name} moved ${distanceInMeters}m.`);
 }
}
class Dog extends Animal{
  constructor(name:string){
    super(name)
 }
  drak(){
    console.log(this.name + " Woof! Woof!")
 }
}
class Snake extends Animal{
 constructor(name:string){
    super(name)
 }
  move(distanceInMeters: number): void {
    console.log(this.name + ":---" + distanceInMeters)
    // 执行父类的move方法
    super.move(distanceInMeters)
 }
}
const d = new Dog("dog")
d.move(100)
d.drak()
const s = new Snake("蛇")
s.move(1000)


访问修饰符



在类中声明的属性与方法,可以添加访问修饰符控制可被访问的范围


TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public 、 private 和 protected


1、public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是public 的

2、private 修饰的属性或方法是私有的,不能在声明它的类的外部访问

3、protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的  

默认为 public


我们可以自由的访问程序里定义的成员,在 TypeScript 里,成员都默认为 public


name 被设置为了 public ,所以直接访问实例的 name 属性是允许的

class Animal {
  public name: string;
  public constructor(theName: string) {
    this.name = theName
 }
  public move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
 }
}


理解 private


当成员被标记成 private 时,它就不能在声明它的类的外部访问

class Animal {
  private name: string;
  public constructor(theName: string) {
    this.name = theName
 }
  public move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
 }
}
let a = new Animal("动物")
console.log(a.name) // Property 'name' is private and only accessible within class 'Animal'.


理解 protected


protected 修饰符与 private 修饰符的行为很相似,但有一点不同,protected 成员在派生类(子类)中仍然可以访问

class Animal {
  protected name: string;
  public constructor(theName: string) {
    this.name = theName
 }
}
class Cat extends Animal{
  constructor(theName:string){
    super(theName)
 }
  public move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
 }
}
let c = new Cat("猫")
c.move(10)


readonly 修饰符



你可以使用 readonly 关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化

class Person {
  readonly name: string;
  constructor (theName: string) {
    this.name = theName;
 }
}
let p = new Person("iwen");
p.name = "Man with the 3-piece suit"; // 错误! name 是只读的.


与访问修饰符共用


注意如果 readonly 和其他访问修饰符同时存在的话,需要写在其后面

class Person {
  public readonly name: string;
  constructor (theName: string) {
    this.name = theName;
 }
}
let p = new Person("iwen");
p.name = "Man with the 3-piece suit"; // 错误! name 是只读的.


存取器



TypeScript 支持通过 getters/setters 来截取对对象成员的访问。它能帮助你有效的控制对对象成员的访问。

class Animal {
  fullName:string
  getFullName(){
    console.log(this.fullName)
 }
}
let a = new Animal();
a.fullName = "itxiaotong"
a.getFullName()
const fullNameMaxLength = 10;
class Person {
  private _fullName: string;
  get fullName(): string {
    return this._fullName;
 }
  set fullName(newName: string) {
    if (newName && newName.length > fullNameMaxLength) {
      throw new Error("fullName has a max length of " + fullNameMaxLength);
   }
    this._fullName = newName;
 }
}
let p = new Person();
p.fullName = "itxiaotong";
if (p.fullName) {
  alert(p.fullName);
}


温馨提示

这里会出现版本问题

1、TypeScript版本问题:增加 tsconfig.json ,并配置

2、编译时版本问题: tsc hello.ts -t es5

 

tsconfig.json

{
  "compilerOptions": {
    "target": "es6"
 }
}


实例方法与静态方法



实例方法我们很熟悉了,就是在类中定义的方法并且通过实例对象调用


使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用


实例方法

class Person {
  public name:string;
  constructor(name:string){
    this.name = name;
 }
  sayHello(){
    console.log(`${this.name}:Hello`)
 }
}
const p = new Person("itxiaotong")
p.sayHello()


静态方法

class Person {
  public name:string;
  constructor(name:string){
    this.name = name;
 }
  sayHello(){
    console.log(`${this.name}:Hello`)
 }
  static sayHi(){
    console.log("Hi")
 }
}
Person.sayHi()


实例属性与静态属性



实例属性我们很熟悉,就是在类中直接定义的属性,可以通过实例对象调用


ES7 提案中,可以使用 static 定义一个静态属性,在TypeScript中也同样适用,通过类名调用


实例属性

class Person {
  public name:string;
  constructor(name:string){
    this.name = name;
 }
}
const p = new Person("itxiaotong")
p.sayHello()


静态属性


class Person {
  public name:string;
  static age = 20
  constructor(name:string){
    this.name = name;
 }
}
console.log(Person.age)


抽象类



什么是抽象类?


首先,抽象类是不允许被实例化的


其次,抽象类中的抽象方法必须被子类实现


abstract 用于定义抽象类和其中的抽象方法

abstract class Animal {
  public name:string;
  public constructor(name:string){
    this.name = name;
 }
  abstract makeSound(): void;
}
class Cat extends Animal{
  public constructor(name:string){
    super(name)
 }
  makeSound(): void {
   console.log(this.name + "叫了")
 }
}
const c = new Cat("猫")
c.makeSound()


接口初探



TypeScript 的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做 “鸭式辨型法” 或 “结构性子类型化”。 在 TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定

义契约


下面通过一个简单示例来观察接口是如何工作的

function printLabel(labeledObj: { label: string }) {
  console.log(labeledObj.label);
}
let myObj = {
  label: "Size 10 Object"
}
printLabel(myObj)


如果对象中是单一参数,那代码还具有可读性,可是如果参数是很多个,则大大降低了可读性


修改为接口处理参数形式

interface LabeledValue {
  label: string;
}
function printLabel(labeledObj: LabeledValue) {
  console.log(labeledObj.label);
}
let myObj = {
  label: "Size 10 Object"
}
printLabel(myObj);
目录
相关文章
|
2月前
|
JavaScript 前端开发 编译器
【小白入门】 浏览器如何识别Typescript?
【10月更文挑战第1天】浏览器如何识别Typescript?
|
3月前
|
JavaScript 前端开发 编译器
TypeScript,从0到入门带你进入类型的世界
该文章提供了TypeScript的入门指南,从安装配置到基础语法,再到高级特性如泛型、接口等的使用,帮助初学者快速掌握TypeScript的基本用法。
|
4月前
|
JavaScript 编译器
typescript 解决变量多类型访问属性报错--工作随记
typescript 解决变量多类型访问属性报错--工作随记
|
6月前
|
JavaScript 前端开发 程序员
typescript入门笔记分享
typescript入门笔记分享
33 0
|
6月前
|
JavaScript 前端开发 C++
typescript 只读属性
typescript 只读属性
|
7月前
|
JavaScript 开发者 索引
【亮剑】探讨了在TypeScript中为对象动态添加属性的三种方式
【4月更文挑战第30天】本文探讨了在TypeScript中为对象动态添加属性的三种方式:1) 使用索引签名允许添加任意属性,如`[key: string]: any`;2) 通过接口和类型别名提供编译时类型检查,例如`interface Person { name: string; age: number; }`;3) 利用类创建具有属性的对象,如`class Person { name: string; age: number; }`。每种方法有其适用场景,开发者可根据需求选择。
705 0
|
7月前
|
JavaScript 安全 前端开发
【亮剑】TypeScript 由于其强类型的特性,直接为对象动态添加属性可能会遇到一些问题
【4月更文挑战第30天】本文探讨了在 TypeScript 中安全地为对象动态添加属性的方法。基础方法是使用索引签名,允许接受任何属性名但牺牲了部分类型检查。进阶方法是接口扩展,通过声明合并动态添加属性,保持类型安全但可能导致代码重复。高级方法利用 OOP 模式的类继承,确保类型安全但增加代码复杂性。选择哪种方法取决于应用场景、代码复杂性和类型安全性需求。
66 0
|
2月前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
56 0
|
2月前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与实用技巧
【10月更文挑战第8天】深入理解TypeScript:类型系统与实用技巧
|
3月前
|
存储 JavaScript
typeScript进阶(11)_元组类型
本文介绍了TypeScript中的元组(Tuple)类型,它是一种特殊的数组类型,可以存储不同类型的元素。文章通过示例展示了如何声明元组类型以及如何给元组赋值。元组类型在定义时需要指定数组中每一项的类型,且在赋值时必须满足这些类型约束。此外,还探讨了如何给元组类型添加额外的元素,这些元素必须符合元组类型中定义的类型联合。
50 0