学习TypeScript(2)
接口interface
接口interface简介
TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
一个简单的例子代入
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
LabelledValue接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个label属性且类型为string的对象。
p.s:类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
初识接口interface
基本的筛选
interface Girls {
name: string;
age: number;
education: string;
isworked ?: string; // ?: 可选项
}
const girl = {
name:'大脚',
age:18,
education:'本科',
isworked:'否'
}
const screenResume = (girl:Girls) => {
girl.age < 24 && girl.education === '本科' && console.log(girl.name + '进入面试')
girl.age >= 24 || girl.education != '本科' && console.log(girl.name + '你被淘汰了')
}
const getResume = (girl:Girls)=>{
console.log(girl.name + '年龄是' + girl.age)
console.log(girl.name + '学历是' + girl.education)
}
screenResume(girl)
getResume(girl)
进一步对interface加深
interface Girls {
name: string;
age: number;
education: string;
isworked ?: string; // ?: 可选项
[propname:string]:any; //写任何值propname,string:它的属性名称是字符串类型;any:属性的值是任何类型的
say():string;//定义一个say()方法,必须有返回值且返回值必须是string
}
// 类的继承
interface Teacher extends Girls{
teach(): string;
}
// 对类进行约束
class xiaojiejie implements Girls{
name = '刘鑫'
age = 32
education = '本科'
say(){
return '欢迎你的加入!'
}
}
const girl = {
name:'大脚',
age:18,
education:'本科',
isworked:'否',
sex:'女',
say() {
return '欢迎你的加入!'
},
teach():string{
return '加油!'
}
}
const screenResume = (girl:Girls) => {
girl.age < 24 && girl.education === '本科' && console.log(girl.name + '进入面试')
girl.age >= 24 || girl.education != '本科' && console.log(girl.name + '你被淘汰了')
}
const getResume = (girl:Teacher)=>{
console.log(girl.name + '年龄是:' + girl.age)
console.log(girl.name + '学历是:' + girl.education)
girl.isworked && console.log(girl.name + '是否工作过:' + girl.isworked)
girl.sex && console.log(girl.name + '性别是:' + girl.sex)
}
screenResume(girl)
getResume(girl)
类
类的概念和使用
class Lady{
content = 'Hi,朋友!'
sayHello(){
return this.content
}
}
const goddess = new Lady()
console.log(goddess.sayHello())
继承
在TypeScript里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类。
在继承中也可以进行对父类的重写及扩展
// 类的继承:父类有啥子类也有啥
class xiaojiejie extends Lady{
// 类的重写
sayHello(){
// 父类进行扩展用super关键字
return super.sayHello()+'你好呀~'
}
sayHi(){
return 'Hi~'
}
}
const goddess = new xiaojiejie()
console.log(goddess.sayHello())
console.log(goddess.sayHi())
公共,私有与受保护的修饰符
默认为public
在TypeScript里,成员都默认为public
私有:private
TypeScript使用的是结构性类型系统。 当我们比较两种不同的类型时,并不在乎它们从何处而来,如果所有成员的类型都是兼容的,我们就认为它们的类型是兼容的。
但当 其中一个类型里包含一个private成员,那么只有当另外一个类型中也存在这样一个private成员, 并且它们都是来自同一处声明时,我们才认为这两个类型是兼容的。 对于protected成员也使用这个规则。
protected修饰符
protected修饰符与private修饰符的行为很相似,但有一点不同,protected成员在派生中也可以访问。
readonly修饰符
使用readonly关键字将属性设置为只读。只读属性必须在声明或构造函数里被初始化。
class Lady{
readonly name: string;
content = 'Hi,朋友!'
sayHello(){
return this.content
}
constructor (theName: string) {
this.name = theName;
}
}
const goddess = new Lady()
console.log(goddess.sayHello())
goddess.name = “电影院的爆米花” //错误的!name是只读的
再一个例子:
readonly修饰符一般也变量前面和private一样加个“_”
class Person{
public readonly _name:string
constructor(name:string){
this._name = name
}
}
const person = new Person('jspang')
person._name = '夏师傅' //错误的!会报错,因为这个声明了是只读属性
console.log(person._name)
类的构造函数
构造函数中有一个关键字construction,construction(){}构建一个方法
简单的调用
class Person {
constructor(public name:string){
}
}
const person= new Person(18)
console.log(person.name)
父类含有构造函数且继承类含有构造函数
class Person {
constructor(public name:string){
}
}
class Teacher extends Person{
constructor(public age:number){
super('jspang')
}
}
const teacher = new Teacher(18)
console.log(teacher.age)
console.log(teacher.name)
父类不含构造函数,继承类含有构造函数
class Person {
}
class Teacher extends Person{
constructor(public age:number){
super()
}
}
const teacher = new Teacher(18)
console.log(teacher.age)
继承的类 只要子类需要构造函数,都必须要先用super调用父类的构造函数传值进去;如果父类没有构造函数也同样要在子类的构造函数中写super,不然会报错!
类的Getter、Setter和static
简单的例子
class xiaojiejie{
// 在constructor的private 变量一般在前面加个_
constructor(private _age:number){}
get age(){
return this._age-10
}
set age(age:number){
this._age = age + 3
}
}
const dajiao = new xiaojiejie(28)
dajiao.age = 25
// 调用get就可以访问到被保护私有变量,get方法:进行一个封装
console.log(dajiao.age)
static的用法
class Girl{
// static:不用再需要创建对象了,可直接通过类名.X()即可获取
static sayHello(){
return 'HI~'
}
}
console.log(Girl.sayHello())
抽象类
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。
下面代码仅是希望能提供根号的理解,打印是打印不出来的。
// 创建一个抽象类,里面包含个抽象方法
abstract class Teacher{
// 因为是个抽象方法,所以不能有{}写具体方法
abstract course()
}
// 都继承Teacher这个类
class Chinese_teacher extends Teacher{
course(){
console.log('语文老师')
}
}
class Math_teacher extends Teacher{
course(){
console.log('数学老师')
}
}
class English_teacher extends Teacher{
course(){
console.log('英语老师')
}
}