美文网首页
TypeScript基础入门介绍(四)之类、接口篇

TypeScript基础入门介绍(四)之类、接口篇

作者: 大脸猫的前端之路 | 来源:发表于2020-02-17 20:31 被阅读0次

    介绍

    传统的JavaScript程序使用函数和基于原型的继承来创建面向对象的类,在es6中,JavaScript程序员能够使用基于类的面向对象的方式,通过引入class关键字,表示定义一个类。TypeScript中允许开发者使用这些特性。

    类的定义

    其实typescript中定义类的方法与ES6相同,在ES6的基础上,加了类型检查。

    //es6中定义类的方法:
    class Person {
         constructor(name){
            this.name = name;    
         }
         run() {
            console.log(this.name);
         }
    }
    //ts中定义类的方法
    class Person {
        public name:string;    //  public关键字可省略
        constructor(name:string){   //构造函数   实例化类的时候触发的方法
            this.name = name;     
        }
        run():void {
            console.log(this.name);
        }
    }
    // 执行方法
    var p=new Person('张三');
    p.run()
    

    继承

    在TypeScript中,我们可以使用常用的面向对象模式。可使用继承(关键字extends、super)来扩展现有的类。

    class Person {
        public name:string;    //  public关键字可省略
        constructor(name:string){   //构造函数   实例化类的时候触发的方法
            this.name = name;     
        }
        run():void {
            console.log(this.name);
        }
    }
    class Web extends Person{
        constructor(name:string){
            super(name);    // 初始化父类的构造函数,必须调用super();
        }
    }
    var w=new Web('张三');
    w.run()
    

    上述例子展示了基本的继承:类从基类中继承了属性和方法。这里, Web是一个派生类,它派生自Person基类,通过extends关键字。派生类通常被称作子类基类通常被称作超类.
    因为Web继承了Person的功能,因此Web的实例能够执行run方法。

    当子类中定义的方法和父类一致时,会执行子类中的方法,这是原型链的查找规则。

    类中的修饰符(public、protected、private)

    public :公有,在当前类里面、 子类 、类外面都可以访问;
    protected:保护类型,在当前类里面、子类里面可以访问 ,在类外部没法访问
    private :私有 ,在当前类里面可以访问,子类、类外部都没法访问

    默认为public

    在TypeScript中,成员默认为public,也可以明确将一个成员标记为public。上面的例子也可这么写:

    class Person {
        public name:string;    //  public关键字可省略
        public constructor(name:string){   //构造函数   实例化类的时候触发的方法
            this.name = name;     
        }
        public run():void {
            console.log(this.name);
        }
    }
    var p=new Person('张三');
    p.run()
    
    理解protected

    protected类型的成员在当前类和子类中都可以访问,但不能在类外部访问。

    // 类外部无法访问保护类型的属性
    class Person {
        protected name:string;    
        constructor(name:string){   
            this.name = name;     
        }
        run():void {
            console.log(this.name);
        }
    }
    class Web extends Person{
        constructor(name:string){
            super(name);   //  这里仍可以访问name,因为web是由person类派生来的
        }
    }
    var p=new Person('张三');
    p.name;  //  error    不能在类外部使用protected类型变量或方法
    

    注意:当派生类构造函数被标记为protected。这意味着这个类不能在包含它的类外被实例化,但是能被继承。

    理解private

    当成员被 标记成private时,它就不能在声明它的类的外部访问。

    class Person {
        private name:string;    
        constructor(name:string){   
            this.name = name;     
        }
        run():void {
            console.log(this.name);
        }
    }
    class Web extends Person{
        constructor(name:string){
            super(name);   
        }
        work():void {
            console.log(this.name);  //  error  私有变量不能在子类中使用
        }
    }
    var p=new Person('张三');
    p.name;  //  error  私有变量不能在类外部使用
    

    静态属性 静态方法

    静态属性及方法存在于类本身而不是类的实例上。使用static关键字定义,如果实例对象想访问静态属性,需在属性age前加类名Person,如下例:

    class Person {
        name:string;    
        static age:number = 20;
        constructor(name:string){   
            this.name = name;     
        }
        static run():void {
            console.log(this.name);
        }
        work():void{ 
              console.log(Person.age);  //  访问静态属性,必须使用类Person调用
        }
    }
    var p = new Person('张三');
    p.run();  //  error   访问静态方法,必须使用类调用
    Person.run();   // right
    

    抽象类 多态

    抽象类作为其他派生类的基类,一般不会直接被实例化。使用abstract关键字定义抽象类和抽象方法。

    抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。abstract抽象方法只能放在抽象类里面。

    abstract class Animal{
        public name:string;
        constructor(name:string){
            this.name=name;
        }
        abstract eat():any;  //抽象方法不包含具体实现并且必须在派生类中实现。 
        run(){
            console.log('其他方法可以不实现')
        }
    }
    // var a=new Animal() /*错误的写法*/
    class Dog extends Animal{
        //抽象类的子类必须实现抽象类里面的抽象方法
        constructor(name:any){
            super(name)
        }
        eat(){
            console.log(this.name+'吃粮食')
        }
    }
    var d=new Dog('小花花');
    d.eat();
    

    多态:父类定义一个方法不去实现,让继承它的子类去实现 每一个子类有不同的表现。

     class Animal {
         name:string;
         constructor(name:string) {
             this.name=name;
         }
         eat(){   //具体吃什么  不知道 ?继承它的子类去实现 ,每一个子类的表现不一样
             console.log('吃的方法')
        }
    }
    class Dog extends Animal{
        constructor(name:string){
             super(name)
        }
       eat(){
           return this.name+'吃粮食'
       }
    }
     class Cat extends Animal{
        constructor(name:string){
           super(name)
        }
        eat(){
          return this.name+'吃老鼠'
       }
    }
    var d = new Dog('小狗');
    var c = new Cat('小花');
    d.eat();  // 小狗吃粮食
    c.eat();  //  小花吃老鼠
    //  对于同一个方法每个子类实例有不同的表现
    

    接口

    接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。 typescript中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。

    属性类接口

    ts中当自定义方法需对传入的参数进行约束时,我们可以这样定义:
    约束传入的参数必须是对象,并且有label属性

    function printLabel(labelInfo:{label:string}):void {
       console.log('printLabel');
    }
    printLabel('hahah'); //错误写法
    printLabel({name:'张三'});  //错误的写法
    printLabel({label:'张三'});  //正确的写法
    

    当需要对批量方法传入的参数进行更新时,可引入接口:行为和动作的规范,对批量方法进行约束.

    interface FullName{
         firstName:string;   //注意;结束
         secondName:string;
    }
    function printName(name:FullName){
         // 必须传入对象  firstName  secondName
        console.log(name.firstName+'--'+name.secondName);
    }
    printName('1213');  //错误
    var obj={   /*传入的参数必须包含 firstName  secondName*/
         age:20,
         firstName:'张',
        secondName:'三'
    };
    printName(obj);   //  输出“张--三”
    

    当接口里的属性不全都是必需的,在某些条件下存在,或者根本不存在时,可在可选属性名字定义的后面加?符号

    函数类型接口

    函数类型接口:对方法传入的参数以及返回值进行约束

    interface encrypt {
      (key:string, value:string):string;
    }
    var md5:encrypt = function(key:string, value:string):string {
      return key+value;
    }
    console.log(md5('name', 'zhangsan'));
    

    对于函数类型的类型检查来说,函数的参数名不需要与接口定义的名字相匹配,比如用下面的代码重写上面的例子:

    var md5:encrypt = function(source:string, src:string):string {
      return source+src;
    }
    

    类类型接口

    对类的约束,和抽象类有点相似
    在C#或Java中,接口通常是用来定义一个类的公共部分,然后创建一个类,通过implements关键字去实现接口。

    在接口中描述方法,在类里实现它。

    interface Animal{
       name:string;
       eat(str:string):void;
    }
    class Dog implements Animal{
        name:string;
        constructor(name:string){
          this.name=name;
        }
        eat(){
          console.log(this.name+'吃粮食')
        }
    }
    var d=new Dog('小黑');
    d.eat();
    

    可索引接口

    可索引接口:是对数组、对象的约束。不太常用

    //可索引接口 对数组的约束
    interface UserArr{   
      [index:number]:string
    }
    var arr:UserArr=['aaa','bbb'];
    console.log(arr[0]);
    var arr:UserArr=[123,'bbb'];  /*错误,索引的值只能是string*/
    console.log(arr[0]);
    
     //可索引接口 对对象的约束
    // 索引为string类型,值也为string类型
    interface UserObj{
         [index:string]:string
    }
    var arr:UserObj={name:'张三'};
    

    扩展接口:接口可以继承接口

    interface Animal{
      eat():void;
    }
    interface Person extends Animal{
      work():void;
    }
    class Programmer{
        public name:string;
        constructor(name:string){
           this.name=name;
        } 
        coding(code:string){
            console.log(this.name+code)
        }
    }
    class Web extends Programmer implements Person{
         constructor(name:string){
             super(name)
         }
         eat(){
             console.log(this.name+'喜欢吃馒头')
         }
         work(){
          console.log(this.name+'写代码');
       } 
    }
    var w=new Web('小李');
    w.eat();
    w.coding('写ts代码');
    

    在上面例子中,定义了两个接口AnimalPerson ,其中Person继承自Animal,又定义programmer类,具有name属性和coding方法,定义的Web类继承自Programmer并实现了Person接口,因此Web实例也有name属性和AnimalPerson接口的方法eat、work、coding

    上一篇TypeScript基础入门(三)主要介绍ts中的函数

    相关文章

      网友评论

          本文标题:TypeScript基础入门介绍(四)之类、接口篇

          本文链接:https://www.haomeiwen.com/subject/dirlfhtx.html