一、 类
class Person {
name: string = '张三'
static age: number = 18
sayHello() {
console.log('hello')
}
static sayYes() {
console.log('yes')
}
}
直接定义的属性是实例属性
,方法是实例方法
,需要通过对象的实例去访问
const per = new Person()
console.log(per.name) // 张三
per.sayHello()
可以修改值
const per = new Person()
per.name = '李四'
console.log(per.name) // 李四
readonly
开头的属性只可读无法修改
class Person {
readonly name: string = '张三'
static age: number = 18
}
使用static
开头的属性是静态属性(类属性)
,方法是类方法
,可以直接通过类去访问
console.log(Person.age)
Person.sayYes()
二、构造函数
class Dog {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
bark() {
console.log(this)
alert('汪汪汪~')
}
}
const dog = new Dog('旺财', 4)
const dog2 = new Dog('小黑', 3)
constructor
为构造函数,在对象被创建时调用。是一个特殊的方法,用于初始化类的实例
constructor
中,this
用于初始化实例属性,是创建实例时的第一步
实例方法中的this
代表调用该方法的实例对象,用于访问实例属性和执行与实例相关的操作,是实例创建后用来对实例进行操作的方法
三、继承
class Animal{
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
bark() {
alert('动物在叫~')
}
}
class Dog extends Animal {
}
class Cat extends Animal {
}
const dog = new Dog('小黑', 5)
const cat = new Cat('小咪', 3)
console.log(dog, cat)
使用继承后,子类将会拥有父类所有的属性和方法
通过继承可以将多个类中公共的代码写到一个父类中,即可让所有的子类都同时拥有父类的属性和方法
如果想在子类中添加一些父类中没有的属性或方法,直接加就行
如果在子类中添加了与父类相同的方法,则子类方法会覆盖掉父类中的方法(方法重写)
class Dog extends Animal {
run() {
console.log(`${
this.name}在跑~`)
}
bark() {
alert('旺旺旺~')
}
}
在类的方法中 super
表示当前类的父类
如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用
class Cat extends Animal {
gender: string
consructor(name: string, age: number, gender: string) {
super(name,age) // 调用父类中的构造函数
this.gender = gender
}
bark() {
super.bark()
}
}
const cat = new Cat('小咪', 3, '雌')
以 abstract
开头的类是 抽象类
,抽象类和其他类区别不大,只是不能用来创建对象,就是专门用来被继承的类
抽象类中可以添加抽象方法,没有方法体,抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract class Animal{
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
abstract bark():void
}
class Cat extends Animal {
bark() {
alert('喵喵喵~')
}
}
四、接口
接口用来定义一个类的结构,也可以当作类型声明去使用
接口中所有的属性都不能有实际的值,只定义结构,里面所有的方法都是抽象方法
interface myInter {
name: string
sayHello(): void
}
定义类时,可以使类去实现一个接口,使类满足接口的要求
class MyClass implements myInter {
name: string
constructor(name: string) {
this.name = name;
}
sayHello() {
console.log('你好~');
}
}
五、属性的封装
让属性变得更加安全,不再直接访问修改属性
class Person {
_name: string
_age: number
constructor(name: string, age: number) {
this._name = name
this._age = age
}
}
const person = new Person('小明', 18)
此时属性是在对象中设置的,可以任意的被修改,会导致对象中的数据变得很不安全
person._name = '小王'
person._age = 20
console.log(person)
TS可以在属性前添加属性的修饰符
①public
修饰的属性可以在任意地方访问和修改,默认值
②private
私有属性,只能在类内部进行访问和修改。通过类中添加方法使得私有属性可以被外部访问
class Person {
private _name: string
private _age: number
constructor(name: string, age: number) {
this._name = name
this._age = age
}
getName() {
return this._name
}
setName(value: string) {
this._name = value
}
getAge() {
return this._age
}
setAge(value: number) {
if(value >= 0) {
this._age = value
}
}
}
const person = new Person('小明', 18)
console.log(person.getName())
person.setName('小王')
getter
方法用来读取属性,setter
方法用来设置属性,它们被称为属性的存取器
class Person {
private _name: string
private _age: number
constructor(name: string, age: number) {
this._name = name
this._age = age
}
get name() {
return this._name
}
set name(value: string) {
this._name = value
}
get age() {
return this._age
}
set age(value: number) {
if(value >= 0) {
this._age = value
}
}
}
const person = new Person('小明', 18)
console.log(person.name)
person.name = '小王'
③protected
受保护的属性,只能在当前类和当前类的子类中访问和修改
class A {
protected num: number
constructor(num: number) {
this.num = num
}
}
class B extends A {
test() {
console.log(this.num)
}
}
class C {
constructor(public name: string, public age: number) {
}
}
// 等价于
class C {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
六、泛型
在定义函数或类时,如果遇到类型不明确就可以使用泛型
function fn<T>(a: T): T {
return a
}
// 可以直接调用具有泛型的函数
fn(10); // 不指定泛型,TS可以自动对类型进行判断
fn<string>('hello'); // 指定泛型
可以指定多个泛型
function fn<T,K>(a: T, b: K): T {
console.log(b)
return a
}
fn<number,string>(10,'hello');
泛型T为Inter实现类
interface Inter {
length: number
}
function fn<T extends Inter>(a: T): number {
return a.length
}
泛型用到类中
class MyClass<T> {
name: T
constructor(name: T) {
this.name = name
}
}
const mc = new MyClass<string>('小明')