本文主要讲解typescript
中类的使用,不对类的定义做过多的讲解;
类的基本属性:封装,多态和继承;
使用class
关键字来定义一个类:
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
eating() {
console.log(this.name + " eating");
}
}
const p = new Person("wendy", 18)
class
的继承:extends
,super
class Student extends Person {
sno: number
constructor(name: string, age: number, sno: number) {
// super调用父类的构造器
super(name, age);
this.sno = sno;
}
eating() {
console.log("student eating");
super.eating();
}
studying() {
console.log("studying");
}
}
const stu = new Student("why", 18, 111);
console.log(stu.name);
console.log(stu.age);
console.log(stu.sno);
class
的多态
class Animal {
action() {
console.log("animal action")
}
}
class Dog extends Animal {
action() {
console.log("dog running!!!")
}
}
class Fish extends Animal {
action() {
console.log("fish swimming")
}
}
class Person extends Animal {
}
// animal: dog/fish
// 多态的目的是为了写出更加具备通用性的代码
function makeActions(animals: Animal[]) {
animals.forEach(animal => {
animal.action()
})
}
makeActions([new Dog(), new Fish(), new Person()])
public
、private
和protected
在TypeScript
中,类的属性和方法支持三种修饰符: public
、private
、protected
public
修饰的是在任何地方可见、公有的属性或方法,默认编写的属性就是public的;private
修饰的是仅在同一类中可见、私有的属性或方法;protected
修饰的是仅在类自身及子类中可见、受保护的属性或方法;public
是默认的修饰符,忽略不写的时候就为public
,我们这里来演示一下private
和protected
。
class Person {
private name: string = ""
// 封装了两个方法, 通过方法来访问name
getName() {
return this.name
}
setName(newName) {
this.name = newName
}
}
const p = new Person()
console.log(p.getName())
p.setName("why")
// protected: 在类内部和子类中可以访问
class Person {
protected name: string = "123"
}
class Student extends Person {
getName() {
return this.name
}
}
const stu = new Student()
console.log(stu.getName())
如果有一个属性我们不希望外界可修改,只希望确定值后直接使用,那么可以使用readonly
:
class Person {
readonly name: string
age?: number
readonly friend?: Person
constructor(name: string, friend?: Person) {
this.name = name
this.friend = friend
}
}
const p = new Person("why", new Person("kobe"))
console.log(p.name)
console.log(p.friend)
// 不可以直接修改friend
// p.friend = new Person("james")
if (p.friend) {
p.friend.age = 30
}
一些私有属性是不能直接访问,或者某些属性我们想要监听它的获取(getter
)和设置(setter
)的过程,这个时候我们可以使用存取器。
class Person {
private _name: string
constructor(name: string) {
this._name = name
}
// 访问器setter/getter
// setter
set name(newName) {
this._name = newName
}
// getter
get name() {
return this._name
}
}
const p = new Person("why")
p.name = "coderwhy"
console.log(p.name)
静态成员是类的属性,而不是实例对象的属性;
class Student {
static time: string = "20:00"
static attendClass() {
console.log("去学习~")
}
}
let wendy = new Student();
console.log(wendy.name);//undefined
console.log(Student.time)
Student.attendClass()
抽象类的特点(abstract
):
function makeArea(shape: Shape) {
return shape.getArea()
}
// 定义一个形状的抽象类
abstract class Shape {
// 定义一个抽象方法
// 抽象方法以abstract开头,没有方法体
// 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract getArea(): number
}
class Rectangle extends Shape {
private width: number
private height: number
constructor(width: number, height: number) {
super()
this.width = width
this.height = height
}
// 重写面积计算的方法
getArea() {
return this.width * this.height
}
}
class Circle extends Shape {
private r: number
constructor(r: number) {
super()
this.r = r
}
// 重写面积计算的方法
getArea() {
return this.r * this.r * 3.14
}
}
const rectangle = new Rectangle(20, 30);
const circle = new Circle(10);
console.log(makeArea(rectangle)); // 求得一个矩形的面积
console.log(makeArea(circle)); // 求得一个圆的面积
类本身也是可以作为一种数据类型:
class Person {
name: string = "123"
eating() {
}
}
const p = new Person()
const p1: Person = {
name: "why",
eating() {
}
}
function printPerson(p: Person) {
console.log(p.name)
}
printPerson(new Person())
printPerson({name: "kobe", eating: function() {}})