在es6中,javaScript新增了class关键字,提出了类的概念,本质上还是构造函数的语法糖,JavaScript程序员将能够使用基于类的面向对象的方式
基础
class Test {
public name: string;
constructor(name) {
this.name = name;
}
public greet() {
return `greet ${this.name}`;
}
}
console.log(new Test('bom').greet()); //greet bom
继承
我们可以使用extends关键字来继承
class Test {
public name: string;
constructor(name) {
this.name = name;
}
public greet() {
return `greet ${this.name}`;
}
}
class Test1 extends Test{
constructor(public name){
super(name)
}
}
console.log(new Test1('bom').greet());//greet bom
这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里, Test1是一个 派生类,它派生自 Test 基类,通过 extends关键字。 派生类通常被称作 子类,基类通常被称作 超类,字类可以使用父类的属性和方法,可以用super关键字去初始化父类的一些属性
我们再来看另外一个例子
class Test {
public name: string;
constructor(name) {
this.name = name;
}
public greet() {
console.log('Test')
}
}
class Test1 extends Test {
constructor(public name) {
super(name);
}
public greet() {
console.log('Test1')
super.greet()
}
}
new Test1('bom').greet() //Test1 Test
派生类包含了一个构造函数,它 必须调用 super(),它会执行基类的构造函数,
在这个例子中我们在Test1类中通过super去调用父类的greet的方法
修饰符
默认 public
其实我们在写class中不声明修饰符 默认就为public
class Test {
public name: string;
public constructor(name) {
this.name = name;
}
public greet() {
console.log('Test')
}
}
私有的private
private修饰符修饰的只能在该类中去使用,不能被实例去调用,也不能被子类去继承使用
class Test {
public name: string;
public constructor(name) {
this.name = name;
}
private greet() {
console.log('Test')
}
}
new Test('bom').greet() // error: 属性“greet”为私有属性,只能在类“Test”中访问。
class Test1 extends Test {
constructor(public name) {
super(name);
}
public greet() {
console.log('Test1')
super.greet() //error: 属性“greet”为私有属性,只能在类“Test”中访问。
}
}
受保护的protected
protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。
对比一下
class Test {
public name: string;
public constructor(name) {
this.name = name;
}
protected greet() {
console.log('Test')
}
}
new Test('bom').greet() //error: 属性“greet”受保护,只能在类“Test”及其子类中访问。
class Test1 extends Test {
constructor(public name) {
super(name);
}
public greet() {
console.log('Test1')
super.greet() //不会报错,可以在字类里面去使用
}
}
new Test1('bom').greet()
只读readonly
用readonly修饰过的属性为只读的,不能被实例进行修改
class Test {
readonly name: string;
public constructor(name) {
this.name = name;
}
public greet() {
console.log('Test')
}
}
new Test('bom').name='123' //无法分配到 "name" ,因为它是只读属性。
静态属性static
被static修饰过的属性可以在不用实例化类的时候就可以被调用
class Test {
public name: string;
public constructor(name) {
this.name = name;
}
static greet() {
console.log('Test');
}
}
Test.greet(); // Test
抽象类abstract
被abstract修饰过的类只能用作其他类的父类去继承,不能被实例化
abstract class Test {
public name: string;
public constructor(name) {
this.name = name;
}
public greet() {
console.log('Test');
}
}
new Test('bom').greet() //error: 无法创建抽象类的实例
只能被继承去使用
abstract class Test {
public name: string;
public constructor(name) {
this.name = name;
}
public greet() {
console.log('Test');
}
}
class Test1 extends Test {
constructor(public name) {
super(name);
}
public greet() {
console.log('Test1');
super.greet();
}
}
new Test1('bom').greet();
存取器
我们可以通过set和get关键字去修饰属性,可以当我们在访问的时候触发get,在修改的时候触发set
class Test {
public _name: string;
constructor(name:string){
this._name=name
}
set name(newVal: string){
console.log('set')
this._name=newVal
}
get name(){
console.log('get')
return this._name
}
}
console.log(new Test('bom').name) //get bom
console.log(new Test('bom').name='jeck') //set jeck
只带有 get不带有 set的存取器自动被推断为 readonly。
把类当作接口去使用
class Test{
x:string;
y:string;
}
interface TestFace extends Test{
z:string
}
let obj: TestFace={
x:'1',
y:'2',
z:'3'
}