文章目录
类的继承
访问修饰符
readonly 修饰符
存取器
实例方法与静态方法
实例属性与静态属性
静态属性
抽象类
接口初探
类的继承
在 TypeScript 里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式,是允许使用继承来扩展现有的类
继承示例
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
dog.move(10);
为 Dog 继承了 Animal 的功能,因此我们可以创建一个 Dog 的实例,它能够 bark() 和 move()
class Animal{
public name:string;
// 温馨提示:子类继承父类,父类存在构造函数,子类必须实现构造函数
constructor(name:string){
this.name = name;
}
move(distanceInMeters:number){
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
drak(){
console.log(this.name + " Woof! Woof!")
}
}
class Snake extends Animal{
constructor(name:string){
super(name)
}
move(distanceInMeters: number): void {
console.log(this.name + ":---" + distanceInMeters)
// 执行父类的move方法
super.move(distanceInMeters)
}
}
const d = new Dog("dog")
d.move(100)
d.drak()
const s = new Snake("蛇")
s.move(1000)
访问修饰符
在类中声明的属性与方法,可以添加访问修饰符控制可被访问的范围
TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public 、 private 和 protected
1、public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是public 的
2、private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
3、protected 修饰的属性或方法是受保护的,它和 private
默认为 public
我们可以自由的访问程序里定义的成员,在 TypeScript 里,成员都默认为 public
name 被设置为了 public ,所以直接访问实例的 name
class Animal {
public name: string;
public constructor(theName: string) {
this.name = theName
}
public move(distanceInMeters: number) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
理解 private
当成员被标记成 private
class Animal {
private name: string;
public constructor(theName: string) {
this.name = theName
}
public move(distanceInMeters: number) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
let a = new Animal("动物")
console.log(a.name) // Property 'name' is private and only accessible within class 'Animal'.
理解 protected
protected 修饰符与 private 修饰符的行为很相似,但有一点不同,protected
class Animal {
protected name: string;
public constructor(theName: string) {
this.name = theName
}
}
class Cat extends Animal{
constructor(theName:string){
super(theName)
}
public move(distanceInMeters: number) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
let c = new Cat("猫")
c.move(10)
readonly 修饰符
你可以使用 readonly
class Person {
readonly name: string;
constructor (theName: string) {
this.name = theName;
}
}
let p = new Person("iwen");
p.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
与访问修饰符共用
注意如果 readonly 和其他访问修饰符同时存在的话,需要写在其后面
class Person {
public readonly name: string;
constructor (theName: string) {
this.name = theName;
}
}
let p = new Person("iwen");
p.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
存取器
TypeScript 支持通过 getters/setters 来截取对对象成员的访问。它能帮助你有效的控制对对象成员的访问。
class Animal {
fullName:string
getFullName(){
console.log(this.fullName)
}
}
let a = new Animal();
a.fullName = "itxiaotong"
a.getFullName()
const fullNameMaxLength = 10;
class Person {
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
if (newName && newName.length > fullNameMaxLength) {
throw new Error("fullName has a max length of " + fullNameMaxLength);
}
this._fullName = newName;
}
}
let p = new Person();
p.fullName = "itxiaotong";
if (p.fullName) {
alert(p.fullName);
}
温馨提示
这里会出现版本问题
1、TypeScript版本问题:增加 tsconfig.json ,并配置
2、编译时版本问题: tsc hello.ts -t es5
tsconfig.json
{
"compilerOptions": {
"target": "es6"
}
}
实例方法与静态方法
实例方法我们很熟悉了,就是在类中定义的方法并且通过实例对象调用
使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用
实例方法
class Person {
public name:string;
constructor(name:string){
this.name = name;
}
sayHello(){
console.log(`${this.name}:Hello`)
}
}
const p = new Person("itxiaotong")
p.sayHello()
静态方法
class Person {
public name:string;
constructor(name:string){
this.name = name;
}
sayHello(){
console.log(`${this.name}:Hello`)
}
static sayHi(){
console.log("Hi")
}
}
Person.sayHi()
实例属性与静态属性
实例属性我们很熟悉,就是在类中直接定义的属性,可以通过实例对象调用
ES7 提案中,可以使用 static
实例属性
class Person {
public name:string;
constructor(name:string){
this.name = name;
}
}
const p = new Person("itxiaotong")
p.sayHello()
静态属性
class Person {
public name:string;
static age = 20
constructor(name:string){
this.name = name;
}
}
console.log(Person.age)
抽象类
什么是抽象类?
首先,抽象类是不允许被实例化的
其次,抽象类中的抽象方法必须被子类实现
abstract
abstract class Animal {
public name:string;
public constructor(name:string){
this.name = name;
}
abstract makeSound(): void;
}
class Cat extends Animal{
public constructor(name:string){
super(name)
}
makeSound(): void {
console.log(this.name + "叫了")
}
}
const c = new Cat("猫")
c.makeSound()
接口初探
TypeScript 的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做 “鸭式辨型法” 或 “结构性子类型化”。 在 TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定
义契约
下面通过一个简单示例来观察接口是如何工作的
function printLabel(labeledObj: { label: string }) {
console.log(labeledObj.label);
}
let myObj = {
label: "Size 10 Object"
}
printLabel(myObj)
如果对象中是单一参数,那代码还具有可读性,可是如果参数是很多个,则大大降低了可读性
修改为接口处理参数形式
interface LabeledValue {
label: string;
}
function printLabel(labeledObj: LabeledValue) {
console.log(labeledObj.label);
}
let myObj = {
label: "Size 10 Object"
}
printLabel(myObj);