创建对象:
类:
类声明引入一个新类型,并定义其字段、方法和构造函数。 定义类后,可以使用关键字new创建实例 可以使用对象字面量创建实例 在以下示例中,定义了Person类,该类具有字段name和surname、构造函数和方法fullName。
export class Person{// 属性 必须要给初始值firstName:string=''lastName:string=''
// 构造函数:给属性初始值,初始化属性
// constructor() {
// console.log('无参函数')
// }constructor( firstName:string,lastName:string) {this.firstName=firstNamethis.lastName=lastName}fullName(){return this.lastName+this.firstName}
}
let pp:Person=new Person('z','s')
//实例字段,通过new对象之后进行访问的字段
pp.firstName='啧啧啧';
字段
字段是直接在类中声明的某种类型的变量。 类可以具有实例字段或者静态字段。 实例字段 实例字段存在于类的每个实例上。每个实例都有自己的实例字段集合。 要访问实例字段,需要使用类的实例。
class Person2{firstName:string=''lastName:string=''//不能有构造函数/函数
}
//字面量创建对象
let p:Person2={ firstName: '三', lastName: '张'}export class Person3{//静态字段static firstName:string=''lastName:string=''
静态字段
使用关键字static将字段声明为静态。静态字段属于类本身,类的所有实例共享一个静态字段。 要访问静态字段,需要使用类名.
//静态函数static a(num1:number,num2:number){Person3.firstName='张三'//不支持this无法直接访问非静态字段/函数//this.lastName='aa'// a2();return num1+num2}
}
//静态字段使用类名进行访问
Person3.firstName='ss'
方法属于类。类可以定义实例方法或者静态方法。静态方法属于类本身,只能访问静态字段。而实例方法既可以访问静态字段,也可以访问实例字段,包括类的私有字段。
继承
一个类可以继承另一个类(称为基类),并使用以下语法实现多个接口 继承类继承基类的字段和方法,但不继承构造函数。继承类可以新增定义字段和方法,也可以覆盖其基类定义的方法。 基类也称为“父类”或“超类”。继承类也称为“派生类”或“子类”。 包含implements子句的类必须 实现列出的接口中定义的所有方法, 但使用默认实现定义的方法除外.
javascript">class Pet{name:string=''sex:string=''static age:number=0constructor(name:string,sex:string) {this.name=namethis.sex=sex}show(){return`昵称 :${this.name},性别:${this.sex}`}
}
//子类 只支持单继承
class Dog extends Pet{//必须调用父类的有参的构造函数constructor(name:string,sex:string) {//super调用父类的构造函数super(name,sex)}type:string=''//重写:子类重写父类的函数//1.方法名相同2.参数类型相同3.返回值类型相同,或是其子类show(){// return`昵称 :${this.name},性别:${this.sex},品种:${this.type}`return super.show()+'品种:'+this.type}a(){this.show()//子类super.show()//父类}
父类访问
关键字super可用于访问父类的实例字段、实例方法和构造函数。在实现子类功能时,可以通过该关键字从父类中获取所需接口
javascript">//子类 只支持单继承
class Dog extends Pet{//必须调用父类的有参的构造函数constructor(name:string,sex:string) {//super调用父类的构造函数super(name,sex)}type:string=''//重写:子类重写父类的函数//1.方法名相同2.参数类型相同3.返回值类型相同,或是其子类show(){// return`昵称 :${this.name},性别:${this.sex},品种:${this.type}`return super.show()+'品种:'+this.type}a(){this.show()//子类super.show()//父类}
方法重写与重载
子类可以重写其父类中定义的方法的实现。重写的方法必须具有与原始方法相同的参数类型和相同或派生的返回类型。 通过重载签名,指定方法的不同调用。具体方法为,为同一个方法写入多个同名但签名不同的方法头,方法实现紧随其后,如果两个重载签名的名称和参数列表均相同,则为错误.
//重载:1.同一个类,方法名相同,参数列表不同,返回值类型相同// shows(a:number){// }// shows(){//// }
}
let pe=new Pet('zs','公')
//子类函数和父类重名,会调用子类函数
pe.show()class Over{//重载aa(x:number):voidaa(x:string):voidaa(x:number|string):void{}
}
class Oo extends Over{aa(x:number):voidaa(x:string):voidaa(x:number|string):void{}
}
构造函数重载签名 我们可以通过编写重载签名,指定构造函数的不同调用方式。具体方法为,为同一个构造函数写入多个同名但签名不同的构造函数头,构造函数实现紧随其后。
如果两个重载签名的名称和参数列表均相同,则为错误。
//重载aa(x:number):voidaa(x:string):voidaa(x:number|string):void{}
}
class Oo extends Over{aa(x:number):voidaa(x:string):voidaa(x:number|string):void{}
}
可见性修饰符
类的方法和属性都可以使用可见性修饰符。 Public(公有) public修饰的类成员(字段、方法、构造函数)在程序的任何可访问该类的地方都是可见的。 Private(私有) private修饰的成员不能在声明该成员的类之外访问 Protected(受保护) protected修饰符的作用与private修饰符非常相似,不同点是protected修饰的成员允许在派生类中访问 getter和setter setter和getter可用于提供对对象属性的受控访问
class Aa{//共有的public a1:string=''//受保护的:本类和子类中使用protected a2:string=''//私有的private a3:string=''
}
class Bb extends Aa{show(){this.a2='asd'// this.a3='ss'}
}
let aa=new Aa();
let bb=new Bb()class pri{private _a1: stringpublic set a1(value: string) {this._a1 = value}public get a1(): string {return this._a1}private _a2: stringpublic set a2(value: string) {this._a2 = value}public get a2(): string {return this._a2}constructor(a1: string, a2: string) {this._a1 = a1this._a2 = a2}}
let p1=new pri('1','2');
p1.a1='a'
Record类型的对象字面量 泛型Record<K, V>用于将类型(键类型)的属性映射到另一个类型(值类型)。常用对象字面量来初始化该类型的值类型K可以是字符串类型或数值类型,而V可以是任何类型
//map键值对 <key,value>泛型
let map:Record<string,string>={'name':'张三','sex':'男','color':'黄'
}
let names=map['name'];
class Stu{name:string=''age:number=0
}
let map2:Record<string,Stu>={'张三':{name:'张三',age:18},'张2':{name:'张2',age:18},'张4':{name:'张4',age:18},'张5':{name:'张5',age:18},'张6':{name:'张6',age:18},
}
let S:Stu=map2['张三'];
接口
接口声明引入新类型。接口是定义代码协定的常见方式。 任何一个类的实例只要实现了特定接口,就可以通过该接口实现多态。 接口通常包含属性和方法的声明
interface Stus{//接口中的方法,没有方法体(方法的实现)eat():voidstudy():number
}
//(实现类)实现接口,必须重写接口中的方法
class Stu1 implements Stus{eat(): void {console.log('学生在吃')}study(): number {console.log('学生在学习')return 100}}
接口属性 接口属性可以是字段、getter、setter或getter和setter组合的形式。 属性字段只是getter/setter对的便捷写法实现接口的类也可以使用以下两种方式
interface Stu2{//接口的属性会在实现类中默认隐式生成getter/setter方法name:stringsex:stringeat():voidstudy():number
}
class Stu3 implements Stu2{name: string=''sex: string=''eat(): void {throw new Error('Method not implemented.')}study(): number {throw new Error('Method not implemented.')}}
let stu3=new Stu3();
stu3.name='123'interface Inte1{a():void
}
interface Inte2 extends Inte1{b():void
}
class Imp1 implements Inte2{b(): void {throw new Error('Method not implemented.')}a(): void {throw new Error('Method not implemented.')}}
interface A1{a():void
}
interface B1{b():void
}
//实现多个接口
class C1 implements A1,B1{b(): void {throw new Error('Method not implemented.')}a(): void {throw new Error('Method not implemented.')}}
接口继承 接口可以继承其他接口,如下面的示例所示继承接口包含被继承接口的所有属性和方法,还可以添加自己的属性和方法。 继承关键字extends
interface Inte1{a():void
}
interface Inte2 extends Inte1{b():void
}
class Imp1 implements Inte2{b(): void {throw new Error('Method not implemented.')}a(): void {throw new Error('Method not implemented.')}}
泛型
泛型类型和函数 泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型。 泛型类和接口 类和接口可以定义为泛型,将参数添加到类型定义中,如以下示例中的类型参数Element:
class Pet{name:string=''play():void{console.log('玩耍')}
}
class Dog extends Pet{play():void{console.log('狗踢皮球')}
}
class Cat extends Pet{play():void{console.log('猫玩狗')}
}
//1.以父类作为形参
//和宠物玩耍
// function play(cat:Cat){
// Cat.play()
// }
// play(new Cat())
function play(pet:Pet){pet.play()
}
play(new Cat())
play(new Dog())
//2,以父类作为返回值
function ly():Pet{let num=Math.random()*10if(num>5){return new Dog()}else {return new Cat()}
}
通配符
泛型中通配符 我们在定义泛型类,泛型方法,泛型接口的时候经常会碰见很多不同的通配符,比如 T,E,K,V 等等,这些通配符又都是什么意思呢? 常用的 T,E,K,V,? 本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成 A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T ,在可读性上可能会弱一些。通常情况下,T,E,K,V,?是这样约定的: ?表示不确定的 类型 T (type) 表示具体的一个类 K V (key value) 分别代表键值中的Key Value E (element) 代表Element ?无界通配符
class Fx<E>{a(e:E):void{console.log(`${e}`)}
}
let fx=new Fx<number[]>();
fx.a([1,2])
//返回数组的最后一个元素
function lastGet(x:number[]):number{return x[x.length]
}
let aa=lastGet([1,2,3,4])
//返回任意类型数组的最后一个元素
function getlast<T>(x:T[]):T{return x[x.length-1]
}
let a2=getlast<String>(['1','2','as'])