TypeScript の 类 接口
创建一个对象
class Person{
public name:string;
public age:number;
constructor(name:string, age:number){
this.name = name;
this.age = age;
}
}
let a = new Person("测试", 15);
console.log(a.name + " --- " + a.age)
继承
class NewPerson extends Person{
public sex: number;
constructor(sex: number){
this.sex = sex;
}
}
由图可见,上面的继承是不正常的,所以这里需要调用其super方法
class NewPerson extends Person{
public sex: number;
constructor(name:string,age:number,sex: number){
super(name,age);
this.sex = sex;
}
}
私有属性
class PrivatePerson{
private name:string;
constructor(name:string){
this.name = name;
}
}
let c = new PrivatePerson("wz");
console.log(c.name) // 提示报错
这个就是私有属性,那么我们该怎么访问这个私有属性呢?
class PrivatePerson{
private name:string;
constructor(name:string){
this.name = name;
}
get getName(){
return this.name;
}
}
let c = new PrivatePerson("wz");
console.log(c.getName)
通过上述的
get
修饰的属性(看起来更像一个方法),便可以获取到私有属性,最后可以通过c.getName
获取到
有get
获取属性,那么是否有set
设置属性呢???
class PrivatePerson{
private name:string;
constructor(name:string){
this.name = name;
}
get getName(){
return this.name;
}
set setName(name: string){
this.name = name
}
}
let c = new PrivatePerson("wz");
console.log(c.getName)
c.setName = "哈哈";
console.log(c.getName)
通过上面
set
的案例,我们应该清楚的看到,其实get
和set
修饰的都不是方法,而是属性,因为方法的调用fn()
,而这个看起来更像是属性的写法,所以这里注意c.setName = "哈哈"
,既然这样,为了美观,我们将上面的进行一个修改
class PrivatePerson{
private _name:string;
constructor(name:string){
this._name = name;
}
get name(){
return this._name;
}
set name(name: string){
this._name = name
}
}
let c = new PrivatePerson("wz");
console.log(c.name)
c.name = "哈哈";
console.log(c.name)
这样看起来就完全一样了
私有属性作用是什么呢?
实现单例模式
class SimpleObject {
//静态方法中只能调用静态变量
private static simpleInfo: SimpleObject;
//私有化构造函数,让其无法被外界`new`出来
private constructor(){}
//提供公共的静态的获取实例方法
public static getInstance(){
//判断实例是否存在
if(!this.simpleInfo){
//不存在就实例化一个
this.simpleInfo = new SimpleObject();
}
//返回实例
return this.simpleInfo;
}
}
以上的单例模式很简单,但是也需要注意几个小点
- 因为我们需要实现"单例模式",所以必须要限制实例化的方式,只能由我们内部提供,所以将
构造函数私有化
,在前面加上private
- 获取实例方法: 因为我们把构造函数
constructor
私有化了,所以外部无法使用new
关键字实例化对象,我们必须要提供的获取实例方法getInstance
必须可以在不实例化的情况下调用,所以这个方法必须使用static
修饰 - 静态方法只能访问静态的数据,所以这里的实例
simpleInfo
也是静态的,并且为了不让其被外部直接调用,所以加上private
实现部分属性只能获取,而无法修改
- 私有属性实现
class PriPerson{
private _name:string;
constructor(name :string){
this._name = name;
}
get name(){
return this._name
}
}
let e = new PriPerson("一个人");
console.log(e.name)
e.name = "不可修改" //报错
- readonly实现
class PriPerson{
public readonly name:string;
constructor(name :string){
this.name = name;
}
}
let e = new PriPerson("一个人");
console.log(e.name)
e.name = "不可修改" //报错
抽象类
有时候需要分类,同一类事物有着公共的特性,公共的方法(但是每个之间实现不同),这个时候我们就可以定义个抽象类,抽出相同的,相同的方法
abstract class Animal{
getEatOrgan(){
return "嘴";
}
abstract eat():string;
}
class People extends Animal{
eat(){
return "使用手抓吃饭";
}
}
class Pig extends Animal{
eat(){
return "使用嘴拱着吃";
}
}
let animals : [string, string] = ["man", "pig"];
animals.forEach((animal) => {
let unknownAnimal:Animal;
unknownAnimal = animal === "man" ? new People() : new Pig();
console.log("吃饭通用器官:" + unknownAnimal.getEatOrgan(),
"各自吃饭方式: " + unknownAnimal.eat());
})
结果
接口的继承
我们常常会定义一些接口,用于类型定义及检测,像下面一样
interface Student{
name:string,
age:number
}
interface Teacher{
name:string,
sex:string
}
const sayHello = (user) => {
console.log(user.name)
}
let st: Student ={
name: '张珊',
age:18
}
let te :Teacher = {
name:"历史",
sex:"男"
}
sayHello(st);
sayHello(te);
但是我们发现,
sayHello
中参数user
的推断类型是
这个不是我们想要的,所以我们去定义这个user
的类型,用什么呢?是Student
还是Teacher
,当然是我全都要了
const sayHello = (user: Student | Teacher) => {
console.log(user.name)
}
思考,当我们新建对象的时候,这个参数类型是不是一直在添加呢?
这个时候就需要使用我们的接口继承(提取出相同的属性,方法,然后其他子类继承该接口)
interface Person{
name:string
}
interface Student extends Person{
age:number
}
interface Teacher extends Person{
sex:string
}
const sayHello = (user:Person) => {
console.log(user.name)
}
let st: Student ={
name: '张珊',
age:18
}
let te :Teacher = {
name:"历史",
sex:"男"
}
sayHello(st);
sayHello(te);
赞 (0)