TypeScript基本語法---10類

相關概念

  • 類(Class):定義了一件事物的抽象特點,包含它的屬性和方法
  • 對象(Object):類的實例,通過 new 生成
  • 面向對象(OOP)的三大特性:封裝、繼承、多態
  • 封裝(Encapsulation):將對數據的操作細節隱藏起來,只暴露對外的接口。外界調用端不需要(也不可能)知道細節,就能通過對外提供的接口來訪問該對象,同時也保證了外界無法任意更改對象內部的數據
  • 繼承(Inheritance):子類繼承父類,子類除了擁有父類的所有特性外,還有一些更具體的特性
  • 多態(Polymorphism):由繼承而產生了相關的不同的類,對同一個方法可以有不同的響應。比如 CatDog 都繼承自 Animal,但是分別實現了自己的 eat 方法。此時針對某一個實例,我們無需瞭解它是 Cat 還是 Dog,就可以直接調用 eat 方法,程序會自動判斷出來應該如何執行 eat
  • 存取器(getter & setter):用以改變屬性的讀取和賦值行爲
  • 修飾符(Modifiers):修飾符是一些關鍵字,用於限定成員或類型的性質。比如 public 表示公有屬性或方法
  • 抽象類(Abstract Class):抽象類是供其他類繼承的基類,抽象類不允許被實例化。抽象類中的抽象方法必須在子類中被實現
  • 接口(Interfaces):不同類之間公有的屬性或方法,可以抽象成一個接口。接口可以被類實現(implements)。一個類只能繼承自另一個類,但是可以實現多個接口



作者:MrWelson
鏈接:https://www.jianshu.com/p/ae672b7a26e3
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

es6類

TypeScript 是面向對象的 JavaScript。

類描述了所創建的對象共同的屬性和方法

TypeScript 支持面向對象的所有特性,比如 類、接口等。

TypeScript 類定義方式如下:

class class_name { 
    // 類作用域
}

定義類的關鍵字爲 class,後面緊跟類名,類可以包含以下幾個模塊(類的數據成員):

  • 字段 − 字段是類裏面聲明的變量。字段表示對象的有關數據。

  • 構造函數 − 類實例化時調用,可以爲類的對象分配內存。

  • 方法 − 方法爲對象要執行的操作。

使用 class 定義類,使用 constructor 定義構造函數。

通過 new 生成新實例的時候,會自動調用構造函數。

 this 關鍵字表示當前類實例化的對象。注意構造函數的參數名與字段名相同。

class Animal {
    userName: string; // 定義屬性
    constructor(name) {  // 定義構造函數對實例進行初始化
        this.userName = name; // 屬性賦值
    };
    sayHi() {  // 定義方法
        return `My name is ${this.userName}`;
    }
}

/** 
 * 創建實例化對象
 * 我們使用 new 關鍵字來實例化類的對象,語法格式如下:
 * var object_name = new class_name([ arguments ])
*/
let cat = new Animal('Tom');
console.log(cat.sayHi()); //My name is Tom

類的繼承

TypeScript 支持繼承類,即我們可以在創建類的時候繼承一個已存在的類,這個已存在的類稱爲父類,繼承它的類稱爲子類。

類繼承使用關鍵字 extends子類除了不能繼承父類的私有成員(方法和屬性)和構造函數,其他的都可以繼承

TypeScript 一次只能繼承一個類,不支持繼承多個類,但 TypeScript 支持多重繼承(A 繼承 B,B 繼承 C)。

語法格式如下:

class child_class_name extends parent_class_name

繼承類的方法重寫

類繼承後,子類可以對父類的方法重新定義,這個過程稱之爲方法的重寫。

其中 super 關鍵字是對父類的直接引用,該關鍵字可以引用父類的屬性和方法

// 類的繼承
class Cat extends Animal {
    color: string;
    constructor(name,color) {
        super(name);  // 調用父類Animal的 contructor(name)
        this.color = color;
    };
    sayHi() {
        // super.sayHi():調用父類的 sayHi()
        return super.sayHi() + '我是一隻' + this.color + '色的貓';
    }
}

let cat2 = new Cat('Tom','橘黃');
console.log(cat2.sayHi()); //My name is Tom我是一隻橘黃色的貓
let cat3 = new Cat('Jerry','yellow');
cat3.color = '黃'
console.log(cat3.sayHi()); //My name is Jerry我是一隻黃色的貓

存取器

使用 getter 和 setter 可以改變屬性的賦值和讀取行爲:

class Animal2{
    userName: string;
    constructor(name) {
        this.userName = name;
    };
    get userName() {
        return 'muzidigbig';
    };
    set userName(value) {
        console.log('setter: ' + value);
    }
}
let a = new Animal2('Kitty'); // setter: Kitty
a.userName = 'Tom';// setter: Tom
console.log(a.userName);// muzidigbig

實例屬性和方法

js中的屬性和方法:

// js中
function Person(name) {
  this.name = name; // 實例屬性
  this.eat = function(){ console.log('eat') };  // 實例方法
}
Person.age = 19; // 靜態屬性
Person.sleep = function(){ console.log('sleep') }; // 靜態方法

// 訪問實例方法和屬性:
var tom = new Person('tom');
console.log(tom.name) // tom
tom.eat();
tom.sleep() // error: tom.sleep is not a function

// 訪問靜態方法和屬性:
console.log(Person.age); // 19
Person.sleep();
Person.eat(); // error: Person.eat is not a function

ES6 中實例的屬性只能通過構造函數中的 this.xxx 來定義:

class Animal {
    constructor(){
            this.name = 'tom';
        }
    eat() {}
}

let a = new Animal();
console.log(a.name); // tom

ES7 提案中可以直接在類裏面定義:

// ts
class Animal {
    name = 'tom';
    eat() {}
}

let a = new Animal();
console.log(a.name); // Jack

靜態屬性和方法

ES7 提案中,可以使用 static 定義一個靜態屬性或方法。靜態方法不需要實例化,而是直接通過類來調用:

// ts
class Animal {
    static num = 42;
    static isAnimal(a) {
        return a instanceof Animal;
    }
}

console.log(Animal.num); // 42
let a = new Animal('Jack');
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function

訪問修飾符

public

公有屬性或方法,可以在任何地方被訪問到,默認所有的屬性和方法都是 public

private

私有屬性或方法,不能在聲明它的類的外部訪問,也不可以在子類中訪問

protected

受保護的屬性或方法,它和 private 類似,區別是它可以在子類中訪問

// 訪問修飾符
class Person {
    public name: string;
    private idCard: number;
    protected phone: number;
    constructor (name,idCard,phone) {
        this.name = name;
        this.idCard = idCard;
        this.phone = phone;
    }
}

let tom = new Person('Tom',42000,13986358544);
console.log(tom.name); // Tom

// console.log(tom.idCard);//error TS2341: Property 'idCard' is private and only accessible within class 'Person'.

// console.log(tom.phone); //error TS2445: Property 'phone' is protected and only accessible within class 'Person' and its subclasses.

class Teacher extends Person {
    constructor(name,idCard,phone) {
        super(name,idCard,phone);
        console.log(this.name);
        console.log(this.phone);
        // console.log(this.idCard); //error TS2341: Property 'idCard' is private and only accessible within class 'Person'.
    }
}

多態

同一個父類的多個子類,可以有不同結果的同名方法

class Person {
  eat(){ console.log('eat') }
}
class A extends Person {
  eat(){ console.log('A eat') }
}
class B extends Person {
  eat(){ console.log('B eat') }
}

抽象類/抽象方法 abstract

abstract 用於定義抽象類和其中的抽象方法。

  1. 抽象類是提供給其他類繼承的基類(父類),是不允許被實例化
  2. 抽象方法只能包含在抽象類中
  3. 子類繼承抽象類,必須實現抽象類中的抽象方法
abstract class Animal {
    abstract eat(); // 抽象方法
    // 普通方法
    sleep(){
      console.log('sleep')
    }
}

let a = new Animal(); // 報錯,抽象類不能被實例化

class Cat extends Animal {
    eat(){ 
        // 父類的eat方法必須被實現
      console.log('eat')
    }
}

類與接口

類可以實現接口。

前面介紹了 接口 可以用來描述 對象(object)的形狀,這一章主要介紹 接口類(class)的行爲 進行抽象。

類實現接口 implements

實現(implements)是面向對象中的一個重要概念。一個類只能繼承自另一個類,不同類之間可能會有一些共有特性,提取多個類的共有特性,作爲一個接口,再用 implements 關鍵字來實現就可以大大提高面向對象的靈活性。

舉例: 人是一個類,人需要吃東西。動物是一個類,動物也需要吃東西。這種情況就可以把 吃東西 提取出來作爲一個接口:

interface Ieat {
   eat();
}

class Person implements Ieat{
  eat(){}
}

class Animal implements Ieat {
  eat(){}
}


 

 

 

 

發佈了246 篇原創文章 · 獲贊 260 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章