简介
- 直接定义的属性是实例属性,需要通过对象的实例去访问
- 使用static开头的属性是静态属性(类属性),可以直接通过类去访问
// 使用class关键字来定义一个类
/*
* 对象中主要包含了两个部分:
* 属性
* 方法
* */
class Person{
/*
* 直接定义的属性是实例属性,需要通过对象的实例去访问:
* const per = new Person();
* per.name
*
* 使用static开头的属性是静态属性(类属性),可以直接通过类去访问
* Person.age
*
* readonly开头的属性表示一个只读的属性无法修改
* */
// 定义实例属性
// readonly name: string = '孙悟空';
name = '孙悟空';
// 在属性前使用static关键字可以定义类属性(静态属性)
// static readonly age: number = 18;
age = 18;
// 定义方法
/*
* 如果方法以static开头则方法就是类方法,可以直接通过类去调用
* */
sayHello(){
console.log('Hello 大家好!');
}
}
const per = new Person();
// console.log(per.name, per.age);
// console.log(Person.age);
构造函数
- constructor 被称为构造函数
- 构造函数会在对象创建时调用 也就是new的过程
class Dog{
name: string;
age: number;
// constructor 被称为构造函数
// 构造函数会在对象创建时调用 也就是new的过程
constructor(name: string, age: number) {
// 在实例方法中,this就表示当前当前的实例
// 在构造函数中当前对象就是当前新建的那个对象
// 可以通过this向新建的对象中添加属性
this.name = name;
this.age = age;
}
bark(){
// 在方法中可以通过this来表示当前调用方法的对象
console.log(this.name);
}
}
const dog = new Dog('小黑', 4);
const dog2 = new Dog('小白', 2);
// console.log(dog);
// console.log(dog2);
dog2.bark();
继承
- 使用继承后,子类将会拥有父类所有的方法和属性
- 通过继承可以将多个类中共有的代码写在一个父类中,这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
- 如果在子类中添加了和父类相同的方法,则子类方法会覆盖掉父类的方法,这种子类覆盖掉父类方法的形式,称为方法重写
// 定义一个Animal类
class Animal{
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello(){
console.log('动物在叫~');
}
}
// 定义一个表示狗的类
// 使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
- 如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用,也就是说只要子类中写了constructor,那么必须要写super
- super()其实就是调用父类的构造函数
- 在子类的方法中 super就表示当前类的父类
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开头的类是抽象类,抽象类和其他类区别不大,只是不能用来创建对象,抽象类就是专门用来被继承的类
- 抽象类中可以添加抽象方法
- 抽象方法使用 abstract开头,没有方法体,抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
// 定义一个抽象方法
// 抽象方法使用 abstract开头,没有方法体
// 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract sayHello():void;
}
class Dog extends Animal{
sayHello() {
console.log('汪汪汪汪!');
}
}
class Cat extends Animal{
sayHello() {
console.log('喵喵喵喵!');
}
}
const dog = new Dog('旺财');
dog.sayHello();
TS可以在属性前添加属性的修饰符
- public 修饰的属性可以在任意位置访问(修改) 默认值
- private 私有属性,私有属性只能在类内部进行访问(修改),通过在类中添加方法使得私有属性可以被外部访问
- protected 受包含的属性,只能在当前类和当前类的子类中访问(修改)
getter VS setter
原本属性可以任意的被修改,将会导致对象中的数据变得非常不安全。通过调用 set 函数进行修改,并在 set 函数中对设置进行一些控制,可以放置属性被任意修改 比如 将 age赋值为一个负数等
原先
// 定义一个表示人的类
class Person{
// TS可以在属性前添加属性的修饰符
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中设置方式
get name(){
// console.log('get name()执行了!!');
return this._name;
}
set name(value){
this._name = value;
}
get age(){
return this._age;
}
set age(value){
// 在方法中可以对变量进行一些设置
if(value >= 0){
this._age = value
}
}
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; num 变量只能在类里面访问 在外面访问不到
其他书写形式
/* 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);