//类可以理解为模板,通过模板可以实例化对象
//面向对象的定义及使用
class Person{
//定义属性
name:string
age:number
gender:string
//构造方法
constructor(name:string,age:number,gender:string){
//更新属性数据
this.name=name
this.age=age
this.gender=gender
}
// 一般方法
sayHi(str:string){
console.log(`你好。我是${this.name},${str}`)
}
}
//实例化对象
const person1=new Person('wy',18,'女')
person1.sayHi('哈哈');
//#类的继承
//继承:类与类之间的关系
//继承后类与类之间的叫法
//A类继承了B这个类,那么A类叫做子类,B类叫做基类
//子类--->派生类
//基类--->超类(父类)
//一旦发生了继承的关系。就出现了父子类的关系(叫法)
//定义一个类继承自Person
class Student extends Person{
constructor(name:string,age:number,gender:string){
//调用的是父类中的构造函数,使用的是super
super(name,age,gender)
}
//也可以调用父类中的方法
sayHi(){
super.sayHi('嘻嘻');//父类中的方法需要传参
}
}
//实例化student
const student1=new Student('龙龙',19,'男');
student1.sayHi();
//总结:类与类之间如果要有继承关系,需要使用extends关键字
//子类中可以调用父类的构造函数,使用的是super关键字。包括调用父类中的实力方法,也可以使用super
//子类中可以重写父类的方法
//类的多态:父类的引用指向了子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为
//定义一个父类
class Animal{
name:string
constructor(name:string){
this.name=name
}
run(distance:number=0){
console.log(`${this.name} 跑了${distance}米`)
}
}
// 定义一个子类
class Dog extends Animal{
constructor(name:string){
super(name)
}
run(distance:number=5){
super.run(distance)
}
}
// 定义一个子类
class Cat extends Animal{
constructor(name:string){
super(name)
}
run(distance:number=10){
super.run(distance)
}
}
const animal1:Animal=new Animal('动物');
animal1.run();
const dog1:Animal=new Dog('小黄');
dog1.run();
const cat1:Animal=new Cat('咪咪');
cat1.run()
console.log('=============')
function totalAnimal(ani:Animal){
ani.run()
}
totalAnimal(dog1);
totalAnimal(cat1);
//修饰符(类中的成员的修饰符):主要是描述类中的成员(属性,构造函数,方法)的可访问性
//类中的成员都有自己的默认的访问修饰符,public
//public修饰符,类中的成员默认的修饰符,代表的是公共的。任何位置都可以访问类中的成员
//private修饰符,类中的成员如果使用private来修饰,那么外部是不能访问这个成员的数据的,当然子类也无法访问成员中的数据
//protected修饰符,类中的成员如果使用protected来修饰,那么外部是无法访问这个成员的数据的,当然子类是可以访问该成员数据的。
/*
访问修饰符: 用来描述类内部的属性/方法的可访问性
public: 默认值, 公开的外部也可以访问
private: 只能类内部可以访问
protected: 类内部和子类可以访问
*/
class Animal {
public name: string
public constructor (name: string) {
this.name = name
}
public run (distance: number=0) {
console.log(`${this.name} run ${distance}m`)
}
}
class Person extends Animal {
private age: number = 18
protected sex: string = '男'
run (distance: number=5) {
console.log('Person jumping...')
super.run(distance)
}
}
class Student extends Person {
run (distance: number=6) {
console.log('Student jumping...')
console.log(this.sex) // 子类能看到父类中受保护的成员
// console.log(this.age) // 子类看不到父类中私有的成员
super.run(distance)
}
}
console.log(new Person('abc').name) // 公开的可见
// console.log(new Person('abc').sex) // 受保护的不可见
// console.log(new Person('abc').age) // 私有的不可见
//readonly修饰符:首先是一个关键字,对类中的属性成员进行修饰,修饰后,该属性成员,就不能在外部被随意修改了
//构造函数中,可以对只读的属性成员的数据进行修改
//如果构造函数中没有任何的参数,类中的属性成员此时有i经使用readonly进行修饰了。那么外部是不能对这个属性值进行更改的。
//构造函数中的参数可以使用readonly进行修饰,一旦修饰了。那么该类中就有了这个只读的成员属性了。外部可以访问,但不能修改
//构造函数中的参数可以使用public,以及private和protected进行修饰,无论是哪个进行修饰,该类中都会自动添加这么一个属性成员
//例如构造函数中的name参数,一旦使用readonly进行修饰后,那么该name参数可以叫参数属性
//例如构造函数中的name参数,一旦使用readonly进行修饰后。那么当前的类中就有了一个name的属性成员
//构造函数中的name参数,一旦使用readonly进行修饰后,外部也是无法修改类中的name属性成员值的。
抽象类做为其它派生类的基类使用。 它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节。 abstract
关键字是用于定义抽象类和在抽象类内部定义抽象方法。抽象类是为子类来服务的。
//类的存取器:让我们可以有效的控制对 对象中的成员的访问。通过getters和setters来进行操作
class Person{
//外部可以传入姓氏和名字数据,同时使用set和get控制姓名的数据。外部可以进行修改操作
firstName:string
lastName:string
get fullName(){
return this.firstName+'-'+this.lastName
}
set fullName(val){
const names=val.split('_')
this.firstName=names[0]
this.lastName=names[1];
}
}
const person1:Person=new Person();
person1.fullName="w_y"
console.log(person1);
console.log(person1.fullName);
/*
抽象类
不能创建实例对象, 只有实现类才能创建实例
可以包含未实现的抽象方法
*/
abstract class Animal {
abstract cry ()
run () {
console.log('run()')
}
}
class Dog extends Animal {
//子类中可以使用抽象类来实例化
cry () {
console.log(' Dog cry()')
}
}
const dog = new Dog()
dog.cry()
dog.run()