TS 笔记 ---Class
// 使用class关键字来定义一个类
/*
\* 对象中主要包含了两个部分:
\* 属性
\* 方法
*/
class Person {
/*
\* 直接定义的属性是实例属性,需要通过对象的实例去访问:
\* const per = new Person();
\* per.name
*
\* 使用static开头的属性是静态属性(类属性),可以直接通过类去访问
\* Person.age
*
\* readonly开头的属性表示一个只读的属性无法修改
*/
/*
定义实例属性(new出实例之后才能访问的属性)
*/
// name: string = '孙悟空';
// age:number = 18;
/*
定义静态属性:在属性前使用static关键字可以定义类属性(静态属性)
*/
// static age: number = 18;
/*
readonly开头的属性表示一个只读的属性无法修改
*/
// readonly name: string = '孙悟空';
name: string = '孙悟空';
age:number = 18;
/*
\* 定义方法:如果方法以static开头则方法就是类方法,可以直接通过类去调用
*/
// 实例方法
sayHello(){
console.log('Hello 大家好!');
}
// 类方法
static sayHello(){
console.log('Hello 大家好!');
}
}
/* 创建实例 */
const per = new Person();
/* 属性 */
// 访问实例属性
console.log(per);
console.log(per.name, per.age);
// 访问静态(类)属性
// console.log(Person.age);
// 如果是readonly类型,则无法修改
// 下面的代码报错
// per.name = 'tom';
/* 方法 */
// 访问实例方法
per.sayHello();
// 访问静态方法
Person.sayHello();
constructor
class Dog {
name: string;
age: number;
// constructor 被称为构造函数
// 构造函数会在对象创建时调用
// TS中仅能创建一个构造函数!
constructor(name: string, age: number) {
// 在实例方法中,this就表示当前当前的实例
// 在构造函数中的当前对象就是新建的那个对象
// 可以通过this向新建的对象中添加属性
this.name = name;
this.age = age;
}
bark() {
// alert('汪汪汪!');
// 在方法中可以通过this来表示当前调用方法的对象
console.log(this.name);
}
}
const dog = new Dog('小黑', 4);
const dog2 = new Dog('小白', 2);
console.log(dog);
console.log(dog2);
dog2.bark();
extends
(function () {
// 定义一个Animal类
class Animal {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello() {
console.log('动物在叫~');
}
}
/*
\* Dog extends Animal
\* - 此时,Animal被称为父类,Dog被称为子类
\* - 使用继承后,子类将会拥有父类所有的方法和属性
\* - 通过继承可以将多个类中共有的代码写在一个父类中,
\* 这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
\* 如果希望在子类中添加一些父类中没有的属性或方法直接加就行
\* - 如果在子类中添加了和父类相同的方法,则子类方法会覆盖掉父类的方法
\* 这种子类覆盖掉父类方法的形式,我们称为方法重写
*
*/
// 定义一个表示狗的类
// 使Dog类继承Animal类
class Dog extends Animal {
run() {
console.log(`${this.name}在跑~~~`);
}
sayHello() {
console.log('汪汪汪汪!');
}
}
// 定义一个表示猫的类
// 使Cat类继承Animal类
class Cat extends Animal {
sayHello() {
console.log('喵喵喵喵!');
}
}
const dog = new Dog('旺财', 5);
const cat = new Cat('咪咪', 3);
console.log(dog);
dog.sayHello();
dog.run();
console.log(cat);
cat.sayHello();
})();
super
(function () {
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayHello() {
console.log('动物在叫~');
}
}
class Dog extends Animal {
age: number;
// 如果在子类中写了构造函数,在子类构造函数中"必须"对父类的构造函数进行调用
constructor(name: string, age: number) {
// 调用父类的构造函数
super(name);
this.age = age;
}
sayHello() {
// 在类的方法中 super就表示当前类的父类
//super.sayHello();
console.log('汪汪汪汪!');
}
}
const dog = new Dog('旺财', 3);
dog.sayHello();
})();
abstract
(function () {
/*
\* 以abstract开头的类是抽象类,
\* 抽象类和其他类区别不大,只是不能用来创建对象
\* 抽象类就是专门用来被继承的类
*
\* 抽象类中可以添加抽象方法
*/
abstract class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
// 定义一个抽象方法
// 抽象方法使用 abstract开头,没有方法体
// 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract sayHello(): void;
}
// 下面的代码会报错
// const an = new Animal();
class Dog extends Animal {
sayHello() {
console.log('汪汪汪汪!');
}
}
class Cat extends Animal {
sayHello() {
console.log('喵喵喵喵!');
}
}
const dog = new Dog('旺财');
dog.sayHello();
})();
public private protected getter setter
(function () {
// 定义一个表示人的类
class Person {
// TS可以在属性前添加属性的修饰符
/*
\* public 修饰的属性可以在任意位置访问(修改)默认值
\* private 私有属性,私有属性只能在类内部进行访问(修改)
\* - 通过在类中添加方法使得私有属性可以被外部访问
\* protected 受保护的属性,只能在当前类和当前类的子类中访问(修改)
*
*/
private _name: string;
private _age: number;
constructor(name: string, age: number) {
this._name = name;
this._age = age;
}
/*
\* getter方法用来读取属性
\* setter方法用来设置属性
\* - 它们被称为属性的存取器
*/
// 定义方法,用来获取name属性
// getName(){
// return this._name;
// }
// 定义方法,用来设置name属性
// setName(value: string){
// this._name = value;
// }
// getAge(){
// return this._age;
// }
// setAge(value: number){
// // 判断年龄是否合法
// if(value >= 0){
// this._age = value;
// }
// }
// TS中设置getter方法的方式
// 此时再使用per.name时,实际上是调用了get name()方法!
get name() {
console.log('get name()执行了!!');
return this._name;
}
// TS中设置setter方法的方式
// 此时再使用per.name = xxx时,实际上是调用了set name()方法!
set name(value) {
console.log('set name()执行了!!');
this._name = value;
}
get age() {
return this._age;
}
set age(value) {
if (value >= 0) {
this._age = value
}
}
}
const per = new Person('孙悟空', 18);
/*
\* 现在属性是在对象中设置的,属性可以任意的被修改,
\* 属性可以任意被修改将会导致对象中的数据变得非常不安全
*/
// per.setName('猪八戒');
// per.setAge(-33);
per.name = '猪八戒';
per.age = -33;
console.log(per);
/*
\* protected演示
*/
class A {
protected num: number;
constructor(num: number) {
this.num = num;
}
}
class B extends A {
test() {
console.log(this.num);
}
}
const b = new B(123);
// b.num = 33;
/*
\* 可以直接将属性定义在构造函数中
*
\* 下面两个构造方法效果是一样的!
*/
/*
class C{
name: string;
age: number
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}*/
class C {
// 可以直接将属性定义在构造函数中
constructor(public name: string, public age: number) {
}
}
const c = new C('xxx', 111);
console.log(c);
})();
本文笔记来自-尚硅谷2021版TypeScript教程(李立超老师TS新课)