zoukankan      html  css  js  c++  java
  • TypeScript 类

    传统的js是使用函数和原型链的方式用来模拟类

    es6中加入了类,class关键字

    // 定义类
    class Greeter {
    	greeting: string;
    	constructor(message: string){
    		this.greeting = message;    // 使用this表示访问的是类成员 
    	}
    	greet() {
    		return "Hello," + this.greeting;
    	}
    }
    
    // 创建对象
    let greeter = new Greeter("World");
    

    编译后的js文件如下
    es5

    // 定义类
    var Greeter = /** @class */ (function () {
        function Greeter(message) {
            this.greeting = message;
        }
        Greeter.prototype.greet = function () {
            return "Hello," + this.greeting;
        };
        return Greeter;
    }());
    // 创建对象
    var greeter = new Greeter("World");
    //# sourceMappingURL=out.js.map
    

    es6

    // 定义类
    class Greeter {
        constructor(message) {
            this.greeting = message;
        }
        greet() {
            return "Hello," + this.greeting;
        }
    }
    // 创建对象
    let greeter = new Greeter("World");
    //# sourceMappingURL=out.js.map
    

    继承

    在ts中可以使用类似于Java中的类的继承。

    // 定义类
    class Animal {
    	move(distanceInMeters: number = 0) {	// 定义一个方法
    		console.log("class - Animal move 方法" + distanceInMeters);
    	}
    }
    
    // 定义继承类
    class Dog extends Animal {
    	bark() {
    		console.log("Dog!");
    	}
    }
    
    const dog = new Dog();	// 创建给予Dog类的对象
    dog.bark();	// 调用继承类的方法bark()
    dog.move(10);	// 调用父类的move方法
    dog.bark();
    
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        }
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    // 定义类
    var Animal = /** @class */ (function () {
        function Animal() {
        }
        Animal.prototype.move = function (distanceInMeters) {
            if (distanceInMeters === void 0) { distanceInMeters = 0; }
            console.log("class - Animal move 方法" + distanceInMeters);
        };
        return Animal;
    }());
    // 定义继承类
    var Dog = /** @class */ (function (_super) {
        __extends(Dog, _super);
        function Dog() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        Dog.prototype.bark = function () {
            console.log("Dog!");
        };
        return Dog;
    }(Animal));
    var dog = new Dog(); // 创建给予Dog类的对象
    dog.bark(); // 调用继承类的方法bark()
    dog.move(10); // 调用父类的move方法
    dog.bark();
    //# sourceMappingURL=out.js.map
    

    超类

    class Animal {
    	name: string;
    	constructor(theName: string){
    		this.name = theName;
    	}
    	move(distanceInMeters: number = 0){
    		console.log("distanceInMeters " + distanceInMeters);
    	}
    }
    
    class Snake extends Animal {
    	constructor(name: string){
    		super(name);	// 调用父类的构造方法,在构造函数访问this之前,必须调用一次 super()
    	};
    	move(distanceInMeters = 45){	// 重写父类的move方法
    		console.log("Galloping...");
    		super.move(distanceInMeters);	// 调用父类的move方法
    	}
    };
    
    class Horse extends Animal {
    	constructor(name: string){
    		super(name);	// 调用父类的构造方法
    	}
    	move(distanceInMeters = 45){	// 重写move方法
    		console.log("Galloping...");
    		super.move(distanceInMeters);	// 调用父类的move
    	}
    }
    
    // 调用基类的派生类即Snake类,使用的是基类的构造方法,重写了基类的move方法,并在子类的move方法中调用了父类的move方法
    let sam = new Snake("Sammy the Python");
    let tom: Animal;	// 声明tom对象,其为Animal类
    tom = new Horse("Tommy the Palomino");	// 此处赋值为Horse类,重写了Animal中的move方法
    
    sam.move();
    tom.move();
    
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        }
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    var Animal = /** @class */ (function () {
        function Animal(theName) {
            this.name = theName;
        }
        Animal.prototype.move = function (distanceInMeters) {
            if (distanceInMeters === void 0) { distanceInMeters = 0; }
            console.log("distanceInMeters " + distanceInMeters);
        };
        return Animal;
    }());
    var Snake = /** @class */ (function (_super) {
        __extends(Snake, _super);
        function Snake(name) {
            return _super.call(this, name) || this;
        }
        ;
        Snake.prototype.move = function (distanceInMeters) {
            if (distanceInMeters === void 0) { distanceInMeters = 45; }
            console.log("Galloping...");
            _super.prototype.move.call(this, distanceInMeters); // 调用父类的move方法
        };
        return Snake;
    }(Animal));
    ;
    var Horse = /** @class */ (function (_super) {
        __extends(Horse, _super);
        function Horse(name) {
            return _super.call(this, name) || this;
        }
        Horse.prototype.move = function (distanceInMeters) {
            if (distanceInMeters === void 0) { distanceInMeters = 45; }
            console.log("Galloping...");
            _super.prototype.move.call(this, distanceInMeters); // 调用父类的move
        };
        return Horse;
    }(Animal));
    // 调用基类的派生类即Snake类,使用的是基类的构造方法,重写了基类的move方法,并在子类的move方法中调用了父类的move方法
    var sam = new Snake("Sammy the Python");
    var tom; // 声明tom对象,其为Animal类
    tom = new Horse("Tommy the Palomino"); // 此处赋值为Horse类,重写了Animal中的move方法
    sam.move();
    tom.move();
    //# sourceMappingURL=out.js.map
    

    公有私有,保护修饰符

    public 默认

    public为默认

    class Animal {
    	public name: string;
    	public constructor(theName: string){
    		this.name = theName;
    	}
    	public move(distanceInMeters: number){
    		console.log("move 方法");
    	}
    }
    
    
    var Animal = /** @class */ (function () {
        function Animal(theName) {
            this.name = theName;
        }
        Animal.prototype.move = function (distanceInMeters) {
            console.log("move 方法");
        };
        return Animal;
    }());
    //# sourceMappingURL=out.js.map
    

    private 保护成员

    不能被外部访问

    class Person {
    	protected name: string;	// 保护成员,对外不可访问
    	constructor(name:string){
    		this.name = name;
    	}
    }
    
    class Employee extends Person {
    	private department: string;
    
    	constructor(name:string, department:string){
    		super(name);	// 调用父类的构造方法
    		// 接着才能使用this
    		this.department = department;
    	}
    
    	public getElevatorPitch(){
    		return "hello !" + name;	// 通过实例访问父类的name
    	}
    }
    
    let howard = new Employee("Howard", "sales");
    console.log(howard.getElevatorPitch());
    //console.log(howard.name);	//访问父类的,失败,不能直接被访问,但是能被派生方法所访问
    
    PS C:UsersmingmDesktop	s> tsc
    Active code page: 65001
    PS C:UsersmingmDesktop	s>
    
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        }
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    var Person = /** @class */ (function () {
        function Person(name) {
            this.name = name;
        }
        return Person;
    }());
    var Employee = /** @class */ (function (_super) {
        __extends(Employee, _super);
        function Employee(name, department) {
            var _this = _super.call(this, name) || this;
            // 接着才能使用this
            _this.department = department;
            return _this;
        }
        Employee.prototype.getElevatorPitch = function () {
            return "hello !" + name; // 通过实例访问父类的name
        };
        return Employee;
    }(Person));
    var howard = new Employee("Howard", "sales");
    console.log(howard.getElevatorPitch());
    //console.log(howard.name);	//访问父类的,失败,不能直接被访问,但是能被派生方法所访问
    //# sourceMappingURL=out.js.map
    
    // 构造函数使用保护
    class Person {
    	protected name: string;
    	protected constructor(theName:string){	// 构造方法,进行保护
    		this.name = theName;
    	}
    }
    
    class Employee extends Person {
    	private department: string;
    
    	constructor(name: string, department:string){
    		super(name);
    		this.department = department;
    	}
    
    	public getElevatorPitch() {
    		return "hello" + this.department + this.name;
    	}
    }
    
    let howard = new Employee("Howard", "Sales");
    
    //let john = new Peron("John");	//错误,构造函数被保护,不能在外部访问
    
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        }
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    // 构造函数使用保护
    var Person = /** @class */ (function () {
        function Person(theName) {
            this.name = theName;
        }
        return Person;
    }());
    var Employee = /** @class */ (function (_super) {
        __extends(Employee, _super);
        function Employee(name, department) {
            var _this = _super.call(this, name) || this;
            _this.department = department;
            return _this;
        }
        Employee.prototype.getElevatorPitch = function () {
            return "hello" + this.department + this.name;
        };
        return Employee;
    }(Person));
    var howard = new Employee("Howard", "Sales");
    //let john = new Peron("John");	//错误,构造函数被保护,不能在外部访问
    //# sourceMappingURL=out.js.map
    

    readonly修饰符

    将属性设置为只读

    class Octopus {
    	readonly name: string;	// 只读
    	readonly numberOfLegs: number = 8; // 只读
    
    	constructor(theName:string){
    		this.name = theName;
    	}
    }
    let dad = new Octopus("Hello world");
    
    //dad.name = "Hello world";	//设置值。出错,由于为只读
    
    var Octopus = /** @class */ (function () {
        function Octopus(theName) {
            this.numberOfLegs = 8; // 只读
            this.name = theName;
        }
        return Octopus;
    }());
    var dad = new Octopus("Hello world");
    //dad.name = "Hello world";	//设置值。出错,由于为只读
    //# sourceMappingURL=out.js.map
    

    参数属性

    class Octopus {
    	readonly numberOfLegs: number = 9;
    	constructor(readonly name:string){	// 直接定义参数属性
    
    	}
    }
    
    var Octopus = /** @class */ (function () {
        function Octopus(name) {
            this.name = name;
            this.numberOfLegs = 9;
        }
        return Octopus;
    }());
    //# sourceMappingURL=out.js.map
    

    通过get set获取属性

    let passcode = "secret passcode";
    
    class Employee {
    	private _fullName: string;	// 保护成员一般下划线
    
    	get fullName():string {	// get方法
    		return this._fullName;
    	}
    
    	set fullName(newName:string){
    		if (passcode && passcode == "code") {
    			// 进行赋值操作
    			this._fullName = newName;
    		}else {
    			console.log("出现重复")
    		}
    	}
    }
    
    let employee = new Employee();	// 创建对象
    employee.fullName = "Bob";	//调用get方法
    // 下面调用set方法
    if(employee.fullName){
    	console.log(employee.fullName);
    }
    
    
    PS C:UsersmingmDesktop	s> tsc
    Active code page: 65001
    PS C:UsersmingmDesktop	s>
    
    var passcode = "secret passcode";
    var Employee = /** @class */ (function () {
        function Employee() {
        }
        Object.defineProperty(Employee.prototype, "fullName", {
            get: function () {
                return this._fullName;
            },
            set: function (newName) {
                if (passcode && passcode == "code") {
                    // 进行赋值操作
                    this._fullName = newName;
                }
                else {
                    console.log("出现重复");
                }
            },
            enumerable: true,
            configurable: true
        });
        return Employee;
    }());
    var employee = new Employee(); // 创建对象
    employee.fullName = "Bob"; //调用get方法
    // 下面调用set方法
    if (employee.fullName) {
        console.log(employee.fullName);
    }
    //# sourceMappingURL=out.js.map
    

    只能输出es5或更高的版本,不支持输出es3

    静态属性

    当类未被实例化的时候,可以直接访问的为静态属性

    class Grid {
    	static origin = { x: 0, y: 0 };	// 这里类似使用static 
    	calculate(point:{x:number, y:number}){	// 在此处定义了point,
    		let x = point.x - Grid.origin.x	// 前面访问的是poinyt定义的,后面访问的是static定义的origin
    		let y = point.y - Grid.origin.y;	// 同理如上
    		return point.x + point.y;	
    	}
    	constructor(public scale: number) { };
    }
    
    let grid1 = new Grid(1.0);// 对static进行赋值
    let grid2 = new Grid(2.0);
    
    // 访问
    grid1.calculate({x:10, y:10});	
    grid2.calculate({x:10, y:10});
    
    
    var Grid = /** @class */ (function () {
        function Grid(scale) {
            this.scale = scale;
        }
        Grid.prototype.calculate = function (point) {
            var x = point.x - Grid.origin.x; // 前面访问的是poinyt定义的,后面访问的是static定义的origin
            var y = point.y - Grid.origin.y; // 同理如上
            return point.x + point.y;
        };
        ;
        Grid.origin = { x: 0, y: 0 }; // 这里类似使用static 
        return Grid;
    }());
    var grid1 = new Grid(1.0); // 对static进行赋值
    var grid2 = new Grid(2.0);
    // 访问
    grid1.calculate({ x: 10, y: 10 });
    grid2.calculate({ x: 10, y: 10 });
    //# sourceMappingURL=out.js.map
    

    抽象类

    抽象类为其他派生类的基类。

    抽象类不会被实例化

    抽象类用于作为基类,派生出其他类使用。

    // 定义抽象类
    abstract class Department {
    	constructor(public name:string){
    
    	}
    
    	// 定义实现的细节
    	printName():void{
    		console.log("实现细节");
    	}
    
    	// 定义抽象方法,该抽象方法必须在派生类中实现其具体的内容
    	abstract printMeeting(): void;
    }
    
    class AccountingDepartemnt extends Department {
    	constructor(){
    		super("hello world");	// 调用基类的构造方法
    	}
    
    	// 对抽象方法进行完善
    	printMeeting():void{
    		console.log("完善!");
    	}
    
    	// 定义其余的方法
    	generateReports():void{
    		console.log("添加的其他方法")
    	}
    }
    
    // 创建一个抽象类型的引用
    let department: Department;	// 抽象类的引用,类似于定义,可以被抽象类的子类进行实例化,即分配内存空间,不能被抽象类进行实例化,因为抽象类不能分配内存空间,所以不能对抽象类进行new操作
    department = new AccountingDepartemnt();	// 可以进行分配内存空间
    department.printMeeting();	
    
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        }
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    // 定义抽象类
    var Department = /** @class */ (function () {
        function Department(name) {
            this.name = name;
        }
        // 定义实现的细节
        Department.prototype.printName = function () {
            console.log("实现细节");
        };
        return Department;
    }());
    var AccountingDepartemnt = /** @class */ (function (_super) {
        __extends(AccountingDepartemnt, _super);
        function AccountingDepartemnt() {
            return _super.call(this, "hello world") || this;
        }
        // 对抽象方法进行完善
        AccountingDepartemnt.prototype.printMeeting = function () {
            console.log("完善!");
        };
        // 定义其余的方法
        AccountingDepartemnt.prototype.generateReports = function () {
            console.log("添加的其他方法");
        };
        return AccountingDepartemnt;
    }(Department));
    // 创建一个抽象类型的引用
    var department; // 抽象类的引用,类似于定义,可以被抽象类的子类进行实例化,即分配内存空间,不能被抽象类进行实例化,因为抽象类不能分配内存空间,所以不能对抽象类进行new操作
    department = new AccountingDepartemnt(); // 可以进行分配内存空间
    department.printMeeting();
    //# sourceMappingURL=out.js.map
    

    构造函数

    可以使用类似于java中的语法,进行声明构造函数

    class Greeter{
    	greeting: string;
    	constructor(message:string){
    		this.greeting = message;
    	}
    	// 类似于java中声明构造方法
    	greet(){
    		return "hello " + this.greeting;
    	}
    }
    
    // 首先进行创建引用,类似于原生的var,仅仅声明,并未创建引用。但是必须进行声明,声明其为Greeter
    let greeter: Greeter;
    // 进行分配空间
    greeter = new Greeter("world");
    console.log(greeter.greet());
    

    和使用抽象接口一样,当使用抽象接口的时候,必须要进行先创建引用,然后在分配空间
    原生的如下

    var i;  // 在栈上开辟一块空间,进行储存
    i = new Greeter();  // 完成由栈到堆的指向,对象储存在堆中,当然啦,C++允许对象储存在栈中
    

    必须进行两步。

    关于C++堆和栈的类

    静态建立

    使用

    Box Box
    

    如上的方式,将会静态的建立一个对象
    静态建立对象,将会由编译器在栈中分配内存空间。通过移动栈顶指针,挪出适当的位置,在内存空间上调用构造函数,形成一个栈对象,此方法为在栈中储存对象。

    动态建立

    使用

    Box* Box = new Box();
    

    如上的方式,将会动态的建立一个对象。
    使用new操作运算符的时候,将会在堆中分配一块内存空间,完成由栈到对的指向。

    类当做接口使用

    接口,一种传入对象的规范,比喻,水管的水龙头。

    类可以创建出任何类型

    class Point{
    	x: number;
    	y: number;
    }
    
    interface Point3d extends Point{
    	z: number;
    }
    
    let point3d:Point3d = {
    	x:1,
    	y:2,
    	z:4
    }
    

    使用extends,进行创建接口

    var Point = /** @class */ (function () {
        function Point() {
        }
        return Point;
    }());
    var point3d = {
        x: 1,
        y: 2,
        z: 4
    };
    //# sourceMappingURL=out.js.map
    
    在无知的道路上缓步前行
  • 相关阅读:
    6000?
    基本把“主页大巴”做完了
    myDesk
    挂出了
    如何在网页中添加flash文件
    oracle的SQl语句
    打开PHP 提示下载
    实时计字数提醒的文本框
    wampserver无法打开http://localhost
    “ASP.adduser_aspx.GetTypeHashCode()”: 没有找到适合的方法来重写
  • 原文地址:https://www.cnblogs.com/melovemingming/p/9834246.html
Copyright © 2011-2022 走看看