01-类
//! 类 可以理解为模板,通过模板来实例化对象
//! 面向对象的编程思想
(() => {
//* ts中的类的定义和使用
class Person {
//* 定义属性
name: string;
age: number;
//* 定义构造函数:为了将来实例化对象的时候,可以直接对对象的值进行初始化
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
//* 定义实例方法
say(str: string) {
console.log(`我是${this.name},今年${this.age}`, str);
}
}
//* ts中使用类
const person = new Person("不好也行", 15);
person.say("你好");
})();
02-继承
//! 继承 类与类之间的关系
//! 继承后类与类之间的叫法
/**
* ? A继承了B这个类,那么A叫子类,B叫基类
* ? 子类---->派生类
* ? 基类---->超类(父类)
* ? 一旦发生了继承关系,就出现了父子类的关系
*/
(() => {
//定义一个父类
class Person {
//定义属性
name: string; //名字
age: number;
//定义构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
//定义实例方法
say(str: string) {
console.log(`我是${this.name},我${this.age}岁了${str}`);
}
}
// 定义一个子类
class Son extends Person {
constructor(name: string, age: number) {
//! 调用父级的构造函数,用super
super(name, age);
}
//可以调用父类中的方法
say() {
//console.log("我是子级调用了父级");
super.say("哈哈");
}
}
const person = new Person("不好也行", 15);
person.say("father");
const son = new Son("子级", 15);
son.say();
//! 类和类之间如果有继承关系 使用extends
//! 子类如果调用父级的构造函数用super的方法,如果调用父级的方法也用super
//! 子类中可以重写父类的方法
})();
03-多态
//! 多态 父类型的引用指向了子类型的对象
//! 不同类型的对象针对相同的方法,产生了不同的行为
(() => {
//定义一个父类
class Animal {
//* 定义一个属性
name: string;
//* 定义一个构造函数
constructor(name: string) {
//* 更新属性值
this.name = name;
}
//* 实例化
run(distance: number = 0) {
console.log(`跑了${distance}米 `, this.name);
}
}
//定义一个子类
class Dog extends Animal {
constructor(name: string) {
//* 调用父级的构造函数,实现子类中属性的初始化
super(name);
}
//* 实例化
run(distance: number = 5) {
console.log(`跑了${distance}米 `, this.name);
}
}
//再定义一个子类
class Pig extends Animal {
constructor(name: string) {
//* 调用父级的构造函数,实现子类中属性的初始化
super(name);
}
//* 实例化
run(distance: number = 10) {
console.log(`跑了${distance}米 `, this.name);
}
}
//实例化父级
const ani: Animal = new Animal("动物");
ani.run();
//实例化子级
const dog: Dog = new Dog("小狗子");
dog.run();
//实例化子级
const pig: Pig = new Pig("小猪");
pig.run();
console.log("===============");
//* 父子关系,此时用父类类型创建子类的对象
const dog1: Animal = new Dog("小狗子1");
dog1.run();
const pig1: Animal = new Pig("小猪1");
pig1.run();
console.log("===============");
function showRun(ani: Animal) {
ani.run();
}
showRun(dog1);
showRun(pig1);
})();
04-修饰符
//! 修饰符
/**
* *类中成员的修饰符
* *主要是描述类中的成员(属性,构造函数,方法)的可访问性
* *类中的成员都有自己默认的访问修饰符,public
* ! public---公共,是类中成员默认的修饰符,代表的是公共的,任何位置都可以访问类中的成员
* ! private---私有 是私有的,类中的成员如果用private来修饰,外部是无法访问的,当然子类中也无法访问该成员数据
* ! protected---受保护的,只能子类访问,类中的成员如果用protected来修饰,外部是无法访问的
*/
(() => {
class Person {
//? 属性 public 修饰了属性成员
//public name: string;
//? 属性 private 修饰了属性成员
//private name: string;
//? 属性 protected 修饰了属性成员
protected name: string;
public constructor(name: string) {
this.name = name;
}
public set() {
console.log("嗯", this.name);
}
}
class son extends Person {
constructor(name: string) {
super(name);
}
play() {
console.log("玩", this.name);
}
}
const person = new Person("大石窝");
//? 类的外部可以访问类中的属性成员
// console.log(person.name);
// person.set();
//?
const son1 = new son("kk");
son1.play();
})();
05-readonly修饰符
// ! readonly 修饰符
/**
* * 是一个关键字
* * 对类中的成员进行修饰
* * 被修饰的属性成员,不能在外部进行修改了
* ! 构造函数中可以对只读的属性进行修改
* ! 如果构造函数中没有任何参数,类型的属性成员已经经过 readonly 修饰了,那么外部也不可以对属性进行修改
* ! 构造函数中可以用readonly进行修饰,一旦修饰了该类中就有这个只读的成员属性了,外部可以访问但是不能修改
* ! 构造函数可以用 public,private,protected进行修饰, 无论是哪个进行修饰,该类中都会自动的添加这么一个属性成员
*/
(() => {
//! readonly 修饰类中属性
class Person {
// 初始值
readonly name: string;
constructor(name: string) {
this.name = name;
}
say() {
console.log("你好", this.name);
//? 类中的普通方法中也不能修改 readonly 修饰的成员属性
//this.name='??'
}
}
const person = new Person("不好也行");
console.log(person);
console.log(person.name);
// person.name = "??????/";
// console.log(person.name);
person.say();
console.log("-----------------------------------------");
//! readonly 修饰类中的构造函数中的参数
class S {
//? 构造函数中的name参数,一旦使用readonly进行修饰后,该name可以叫做参数属性
//? 构造函数中的name参数,一旦使用readonly进行修饰后,那么S中就有一个name的属性成员
//! 构造函数中的name参数,一旦使用readonly进行修饰后,外部也是无法修改内部name的属性值的
constructor(readonly name: string) {
this.name = name;
}
//? 构造函数中的name参数,一旦使用public进行修饰后,那么S中就有一个公共的name的属性成员
// constructor(public name: string) {
// this.name = name;
// }
//? 构造函数中的name参数,一旦使用private进行修饰后,那么S中就有一个私有的name的属性成员
// constructor(private name: string) {
// this.name = name;
// }
//? 构造函数中的name参数,一旦使用protected进行修饰后,那么S中就有一个受保护的name的属性成员
//? 只能在本类或派生类中使用
// constructor(protected name: string) {
// this.name = name;
// }
}
const s = new S("不好也行A");
console.log(s);
console.log(s.name);
})();
06-存取器
//! 存取器
/**
* * 让我们可以有效的控制对 对象中成员的访问,
* * 通过 getters 和 setters 来进行操作
*/
(() => {
// 外部可以传入姓氏和名字数据,同时使用set和get控制姓名的数据,外部也可以进行修改的操作
class Parson {
firstName: string; //姓氏
lastName: string; //名字
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
//姓名的成员属性,外部可以进行修改和访问
//! 读取器---负责读取数据
get fullName() {
console.log("get中......");
//* 姓名====> 姓氏和名字的拼接
return this.firstName + "_" + this.lastName;
}
//! 设置器---负责设置数据(修改)
set fullName(val) {
console.log("set中......");
console.log(val);
//* 姓名====> 姓氏和名字取到,重新赋值和firstName和lastName
let name = val.split("_");
this.firstName = name[0];
this.lastName = name[1];
}
}
const person: Parson = new Parson("1", "2");
//获取
console.log("get person: ", person.fullName);
//设置
person.fullName = "11111_2";
//console.log("set person: ", person.fullName);
})();
07-静态成员
//! 静态成员
/**
* * 在类中通过static修饰的属性或方法
* * 要么就是静态的属性及静态的方法,也称之为:静态成员
* ! 静态成员在是用的时候是通过类名.的这种方法来调用的
*/
(() => {
class Person {
//? 静态属性
//? 类中默认有一个内置的name属性,所以此时会报错
static name1: string = "????";
//name1: string;
//? 构造函数不能通过static来修饰
constructor(name: string) {
/**
* ? 此时this是实例对象,name1是静态属性
* ? 不能通过实例对象直接调用静态属性来使用
*/
//this.name1 = name1;
}
//? 静态方法
static say() {
console.log("111111111");
}
}
//const person: Person = new Person();
//? 通过实例对象来调用的属性(实例属性)
//console.log(person.name1);
//? 通过实例对象调用的方法(实例方法)
//person.say();
//? 通过类名.静态属性的方式来访问该成员数据
console.log(Person.name1);
//? 通过类名.静态属性的方式来设置该成员数据
Person.name1 = "456465";
console.log(Person.name1);
//? 通过类名.静态属性的方式来调用内部的静态的方法
Person.say();
})();
08-抽象类
//! 抽象类
/**
* * 包含抽象的方法(抽象方法一般没有任何的具体内容实现)
* * 也可以包含实例方法
* ! 抽象类不能被实例化
* * 作用:为了让子类进行实例化及实现内部的抽象方法
* ! 目的或者作用最终都是为子类服务的
*/
(() => {
//定义抽象类
abstract class Animal {
//? 抽象属性
//abstract name: string;
//? 抽象方法
//? 抽象的方法不能有具体的实现
// abstract eat() {
// console.log("就是吃");
// }
abstract eat(): any;
//? 实例方法
say() {
console.log("说话啊");
}
}
// 定义一个子类(派生类)
class Dog extends Animal {
//name: string = "54";
//? 重新实现抽象类中的方法
//? 此时这个方法就是Dog类的实例方法
eat() {
console.log("跪着吃");
}
}
// 实例化dog的对象
const dog: Dog = new Dog();
dog.eat();
//? 调用的是抽象类中的实例方法
dog.say();
// console.log(dog.name);
//?不能实例化抽象类的对象
//const animal:Animal = new Animal();
})();