typescript上手-类(3)

介绍

传统的javascript只有对象,没有类的概念,对于面向对象方式编程没有很好的设计,当发现问题时,已经成千上万的人在使用了,所以大的修改几乎没有,都是各种修修补补,小的语法糖更新,例如es6新加入的类Class,当然class并不是语法糖,但核心还是围绕prototype来玩。

这里先放一个es5定义一个类

	function Cat(name){
		this.name = name;
		this.say = function(){console.log(this.name)}
	}
	var cat1 = new Cat('dahuang')
	cat1.say();
	//可以dir看一下方法还是在_proto_上的 

使用 class定义一个类

	class Cat{
        constructor(name){
            this.name = name;
        }
        say(){ console.log(this.name) }
    }
    var cat1 = new Cat('dahuang')
    cat1.say();

换汤不换药,看起来反正是舒服些了,下面是ts中类的定义

	class Cat {
	    name: string;//属性
	    constructor(name: string) {//构造函数 实例化触发
	        this.name = name;
	    }
	    say():void{//方法
	        console.log(this.name)
	    }
	}
	var cat1 = new Cat('dahuang')
    cat1.say();

执行的顺序是new一个构造了一个cat实例,调用cat类中的构造函数,把传入的dahuang赋值给属性;

继承

继承方面和es6的class的继承也基本一致,通过extends\super

extends

	class Cat {
	    name: string;//属性
	    constructor(name: string) {//构造函数 实例化触发
	        this.name = name;
	    }
	    say(): void {//方法
	        console.log(this.name)
	    }
	}
	class Dog extends Cat{}
	let dog = new Dog('mimi');
	dog.say()
	//mimi

这个例子展示了最基本的继承,Dog是一个派生类,它派生自 Cat基类,通过 extends关键字。派生类通常被称作子类,基类通常被称作超类。派生类从基类中继承了属性和方法。突然这个傻狗有了自己的想法,事情就不那么简单了

	class Cat {
	    name: string;
	    constructor(name: string) {
	        this.name = name;
	    };
	    say(): void {
	        console.log(this.name)
	    }
	}
	class Dog extends Cat{
	    dosth:string
	    constructor(dosth: string){
	        this.dosth = dosth
	    };
	}

这段甚至都不需要编译,在写的时候编辑器就一大票中国红了,并且提示我们派生类的构造函数必须包含super

super

	class Cat {
	    name: string;
	    constructor(name: string) {
	        this.name = name;
	    };
	    say(): void {
	        console.log(this.name)
	    }
	}
	class Dog extends Cat{
	    dosth:string
	    constructor(name:string,dosth: string){
	        super(name)
	        this.dosth = dosth
	    };
	    justdoit():void{
	        console.log(this.dosth)
	    }
	}
	let dog = new Dog('mimi', '撒野尿')
	dog.say()		//mimi
	dog.justdoit()	//撒野尿

这次按照提示加入了super关键字,mimi顺利的完成了它的壮举,可以说这里的super()就是代表了基类的构造函数;

修饰符

ts定义属性的时候提供了三种修饰符,分别是
公共的public
受保护的protected
私有的provite

公共 public

默认为public,表示在类里面、派生类、类以外都可以访问;

在上面的例子里,我们可以自由的访问cat里的属性,ts成员都默认为 public,写全就是

	class Cat {
	    public name: string;
	    constructor(name: string) {
	        this.name = name;
	    };
	    say(){console.log(this.name)}
	}
	class cat1 extends Cat();
	let cat = new Cat('xiaobai')
	let cat1 = new Cat('dahuang')
	cat.name;
	cat.say();
	cat1.name;
	cat1.say();
	//内外子类中都可以访问到

私有的private

在类里面可以进行访问,派生类、类以外都无法访问;

	class Cat {
	    public name: string;
	    constructor(name: string) {
	        this.name = name;
	    };
	    say(){console.log(this.name)}
	}
	class cat1 extends Cat();
	let cat = new Cat('xiaobai')
	let cat1 = new Cat('dahuang')
	cat.name;		//error
	cat.say();		//fine
	cat1.name;		//error
	cat1.say();		//error

受保护的protected

在类里面、派生类里面可以访问,在类外部没法访问

	class Cat {
	    protected name: string;
	    constructor(name: string) {
	        this.name = name;
	    };
	    say(){console.log(this.name)}
	}	    
    class Cat1 extends Cat { };
	let cat1 = new Cat1('dahuang');
    cat1.say();			//fine
    cat1.name1			//error
    let cat = new Cat('xiaobai');
    cat.say()			//fine
    cat.name;			//error

只读readonly

纸面就是只读么,这个说实话我没太看懂官网的文档什么意思,大致吸收到的就是只读属性必须在声明时或构造函数里被初始化。

	class Cat {
	    readonly name: string;
	    constructor(name: string) {
	        this.name = name;
	    };
	    say() { console.log(this.name) }
	}

然后可以缩写试了一下对于几个修饰符是一样的

	class Cat {
	    constructor(public name: string) {};
	    say() { console.log(this.name) }
	}

静态属性 静态方法 static

静态属性并不存在于实例化对象中,而是直接存在与类本身。
在es5中的静态方法和静态属性

	function cat(){ 
		this.say1 = function(){}	//实例方法
	}
	cat.name = 'dahuang'			//静态属性
	cat.say2 = function(){}			//静态方法
	//方法调用
	var p = new Cat();
	p.say1();
	Cat.say2()

ts中定义静态方法和属性

	class Cat{
		public name:string;
		static age:number = 2;
		constructor(name:string){
			this.name = name;
		}
		say(){		//实例方法,实例化后才可调用
			console.log(this.name)
			console.log(this.age)//静态属性this访问会error
			console.log(Cat.name)//访问静态属性
		}
		static work(){//静态方法,无法直接调用类的属性
			console.log('拿耗子')
		}
	}
	Cat.say();//实例方法直接调用会报错
	Cat.work();//静态方法可以直接调用
	console.log(Cat.age)//直接调用静态属性

抽象类 abstract

抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 说人话就是算是一种多态的规范,指定必须要包含那些方法,但是基类本身不去实现

	abstract class Cat {
		constructor(name:string='cat'){}
	    abstract say(): any;
	}
	let cat1 = new Cat()	//error不能创建一个抽象类的实例
	class Cat1 extends Cat{//fine
		say(){console.log('大狗')}
	}
	class Cat2 extends Cat{//error未实现cat中的成员say
		attck(){console.log('小狗')}
	}

你可能感兴趣的:(typescript)