TypeScript学习-类class
公共属性的修饰符:
- public:公共,私有与受保护的修饰符,默认修饰符,外部和内部都能使用
- private:私有的,只能内部类用,外部不能读写
- protected:派生类(子类)可访问
- readonly:外部只能读不能写
- static:静态属性或静态方法
1、类的定义
- 关键字: class
类
class 类名{
属性(静态属性,动态属性)
方法(静态方法,动态方法)
}
class Person {
name: string = 'zhangsan'
// 定义实例属性 (只有实例化后才能调用)
// const per = new Person()
// console.log(per.name)
static age: number = 18
// 定义类属性(静态属性),前加一个static关键字(直接通过类调用)
// console.log(Person.name)
readonly sex: string = '男'
// readonly修饰属性表示不可以修改,只能读
eat() {
console.log('我在吃东西')
}
// 定义实例方法,(只有实例化后才能调用)
// const per = new Person()
// console.log(per.name)
static sleep() {
console.log('我在吃东西')
}
// 定义类静态方法,前加一个static关键字(直接通过类调用)
// console.log(Person.sleep)
}
2、构造函数和this
- 构造函数: 构造函数会在对象创建的时被调用
- this:表示当前的实例,在方法中可以通过this来表示当前调用对象的方法
class Dog {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
eat() {
console.log('我在吃东西')
console.log(this.name)
}
sleep() {
console.log('我在吃东西')
}
}
const dog1 = new Dog('小二哈', 5)
const dog2 = new Dog('哈皮狗', 10)
3、继承
- 两个关键字:extends,super
- extends:用来声明类的继承关系,表示是的关系
- super:调用父类的构造函数或方法
继承
通过继承可以将多个类中共有的代码写在一个父类中,
这样就只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
如果子类和父类名字相同,则会覆盖掉父类方法(方法重写)
class 父类名{
属性(静态属性,动态属性)
方法(静态方法,动态方法)
}
class 子类名 extends 父类名{
...自己的单独拥有的属性和方法
}
class Animal {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
eat() {
console.log('我在吃东西')
console.log(this.name)
}
sleep() {
console.log('我会睡觉觉')
}
}
// 定义一个狗类
// 使Dog类继承Animal类
// 父类: Animal, 子类:Dog
class Dog extends Animal {
sex: string
constructor(name: string, age: number, sex: string) {
super(name,age)
this.sex = sex
}
run() {
console.log('我在跑动')
}
}
class Cat extends Animal {
catch() {
console.log('我在抓老鼠')
}
}
const dog = new Dog('小狗', 5,'女')
console.log(dog.run())
const cat = new Cat('猫咪', 10)
console.log( cat.catch())
4、抽象
- 关键字: abstract
- 抽象类和普通类区别:不能用来创建对象,专门用来被继承的类
- 可以定义抽象方法,子类必须对此抽象方法进行重写
- 抽象方法:必须只能在抽象类中用
abstract class Animal {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
abstract eat():void
}
class Dog extends Animal {
sex: string
constructor(name: string, age: number, sex:string) {
super(name,age)
this.sex = sex
}
eat() {
console.log('我喜欢吃骨头')
}
}
class Cat extends Animal {
eat() {
console.log('我喜欢吃大鱼')
}
}
5、接口
- 两个关键字:interface 、implements
- interface :用来声明类为接口
- implements :类去实现接口
- 接口: 用来定义一个类的结构,用来定义一个类中应该包含那些属性,同时接口也可以当成类型声明去使用,可以被多次使用,但一个类只能一个接口
- 接口只是定义结构,不能有实际的值,方法都是抽象方法
// 接口: 关键字 interface
interface 接口类名 {
属性
方法
}
// 实现 :关键字 implements
class 类名 implements 接口名{
接口类中所有的属性和方法必须都得实现
}
interface myInterface{
name: string
age: number
}
interface myInterface{
sex: string
run():void // 方法
}
// 实现接口
class myClass implements myInterface{
name: string
age: number
sex: string
constructor(name:string,age:number,sex:string){
this.name = name
this.age = age
this.sex = sex
}
run(): void {
throw new Error("Method not implemented.")
}
}
6、泛型
- 在定义函数或者类时,如果遇到类型不明确即可使用泛型
- 有时候需求不明确类型,虽然可以使用any来实现,但是any 不能做约束,不会进行类型判断,后期会出现一些莫名其妙的bug,不建议使用
function fn<T>(a:T):T{
return a
}
let result = fn(10) // 不知道泛型,TS可以自动对类型进行判断
let result2 = fn<string>('指定string的泛型') // 指定泛型,可以在实例化的时候自己定义泛型的所需要的类型
- 泛型可以指定多个
function fn2<T, k>(a:T,b:k):T{
return a
}
fn2<number, string>(123,'hello')
- 对泛型进行约束
interface Inter{
length: number
}
// T extends Inter 表示泛型T是必须Inter实现类
function fn3<T extends Inter>(a:T):number{
return a.length
}
fn3('123')