ArkTS是TypeScriptS的超集,而TS又是JavaScript的超集,意味着有JavaScript编程基础、结合一些TypeScript的使用经验就可以很快上手ArkTS。
作为一门面向对象语言的学习,了解和掌握这门语言的面向对象(封装、继承、多态)、面向接口、面向抽象的知识很有必要。
一、面向对象
1、封装
是面向对象编程中的一个核心概念,它允许将对象的数据(属性)和行为(方法)捆绑在一起,并对外隐藏内部的实现细节。
class Person {// 属性nationality: string = '中国'; // 国籍name?: string; // 姓名age?: number; // 年龄gender?:stringconstructor(name: string, age?: number,gender?:string) {this.name = name;this.age = age;this.gender=gender}// 方法SelfIntroduction(){if (this.age !== undefined && this.age !== null && this.age >0) {console.log(`My name is ${this.name}, and I am ${this.age} years old this year.`);} else {console.log(`My name is ${this.name}`);}}Study(){console.log(`${this.name} is studying mathematics diligently.`);}
}let Student:Person=new Person('小明',undefined,'male')
let Teacher:Person=new Person('宋老师',35,'female')
let Worker:Person=new Person('小王')Student.SelfIntroduction()
Teacher.SelfIntroduction()
Worker.SelfIntroduction()Teacher.Study()
上面声明变量时如果不赋值,可以在变量名后面加?,包括对象的方法调用时传参也可以加?,但是如果后面紧跟着参数,该位置如果不传参数必须是undefined。
这样传递参数时可以是变化的。
这里也可以使用展开运算符来解决多参数传递的问题,例如:
function sum(num1:number,num2:number,...others:number[]):number{let total=num1+num2others.forEach(element => {total+=element});return total
}console.log(sum(1,2).toString())
console.log(sum(1,2,3,4,5).toString())
当然,如果是多个参数传递,灵活一些应该将参数封装为一个(基于接口的)对象。
声明接口:
interface Para{name: stringage: numbergender:string
}
传递参数:
constructor(ParaObj:Para) {this.name = ParaObj.namethis.age = ParaObj.agethis.gender=ParaObj.gender}
实例化:
let Student:Person=new Person({name:'小明',age:18,gender:'男'
})
正规一些的写法:
interface Para{name: stringage: numbergender:string
}class Person {// 属性protected nationality: string = '中国' // 国籍public name: string // 姓名private _age: number // 年龄private _gender:stringconstructor(ParaObj:Para) {this.name = ParaObj.namethis._age = ParaObj.agethis._gender=ParaObj.gender}get age():number{return this._age}set age(value:number){this._age=value}// 方法public SelfIntroduction(){if (this.age !== undefined && this.age !== null && this.age >0) {console.log(`My name is ${this.name}, and I am ${this.age} years old this year.`);} else {console.log(`My name is ${this.name}`);}}
}let Student:Person=new Person({name:'小明',age:18,gender:'男'
})Student.age=25
Student.SelfIntroduction()
console.log(Student.age.toString())
正规一些的写法比较繁琐,但是能有效保护数据,上面的例子中_gender属性没有提供对应的get和set方法,除了初始化能赋值外,外面不能访问。
2、继承
继承允许一个类(子类)继承另一个类(父类)的属性和方法,这有助于代码复用和扩展。
interface Para{name: stringage: number
}class Person {// 属性protected nationality: string = '中国' // 国籍public name: string // 姓名private _age: number // 年龄constructor(ParaObj:Para) {this.name = ParaObj.namethis._age = ParaObj.age}get age():number{return this._age}set age(value:number){this._age=value}// 方法public SelfIntroduction(){if (this.age !== undefined && this.age !== null && this.age >0) {console.log(`My name is ${this.name}, and I am ${this.age} years old this year.`);} else {console.log(`My name is ${this.name}`);}}
}class Student extends Person{//重写构造函数constructor(ParaObj:Para) {super(ParaObj); // 调用父类的构造函数//执行其他操作}Study(){console.log(`${this.name} is studying。`);}
}let Student1:Student=new Student({name:'小明',age:18,
})Student1.age=25
Student1.SelfIntroduction()
console.log(Student1.age.toString())
3、多态
多态是指子类可以重写继承自父类的方法,使得同一个方法在不同的子类中可以有不同的实现。
class Person {// 属性public name: string // 姓名constructor(name:string) {this.name = name}// 方法Action(){console.log('')}
}class Student extends Person{Action(){console.log(`${this.name} is studying。`);}
}class Teacher extends Person{Action(){console.log(`${this.name} is giving a lecture。`);}
}let Student1:Student=new Student('小明')
Student1.Action()
let Teacher1:Teacher=new Teacher('王老师')
Teacher1.Action()
二、面向接口
⑴当需要定义一个类应该具备的方法签名,但不提供方法的具体实现时,使用接口。
⑵当需要实现代码的松耦合,或者需要一个类遵循某些约定和规范时,使用接口。
interface Shape {draw(): void;
}class Circle implements Shape {radius: number;constructor(radius: number) {this.radius = radius;}draw(): void {console.log(`画一个半径为 ${this.radius} 的圆.`);}
}class Rectangle implements Shape {width: number;height: number;constructor(width: number, height: number) {this.width = width;this.height = height;}draw(): void {console.log(`画一个宽为 ${this.width} 高为 height ${this.height}的矩形.`);}
}
继承多接口的例子:
class Person {name: string = '';age: number = 0;constructor(name: string, age: number) {this.name = name;this.age = age;}Info(): string {return `${this.name}, ${this.age}`;}
}interface Introduce {SayHello(): string;
}interface Work{Study():void;
}class Student extends Person implements Introduce,Work {grade: number = 0;constructor(name: string, age: number, grade: number) {super(name, age);this.grade = grade;}SayHello(): string {return `我是${this.grade}年级的学生,名叫${this.name}`;}Study(){console.log(`${this.name} 正在学习`)}
}let Student1:Student = new Student('小明', 18, 9);
console.log(Student1.Info())
console.log(Student1.SayHello());
Student1.Study()
三、面向抽象
⑴当需要在多个子类之间共享代码时,使用抽象类。
⑵当需要强制子类实现某些方法,或者在共性较多的对象间寻求功能上的差异时,使用抽象类。
abstract class Animal {name: string;constructor(name: string) {this.name = name;}//吃abstract eat(food: string): void;//睡,有默认实现sleep(hours: number): void {console.log(`${this.name} is sleeping for ${hours} hours.`);}
}//Dog
class Dog extends Animal {constructor(name: string) {super(name);}eat(food: string): void {console.log(`${this.name} is eating ${food}.`);}
}//Cat
class Cat extends Animal {constructor(name: string) {super(name);}eat(food: string): void {console.log(`${this.name} is eating ${food}.`);}
}let dog1:Dog=new Dog('虎仔')
let cat1:Cat=new Cat('小花')dog1.eat('骨头')
cat1.eat('猫食')
dog1.sleep(2)