TypeScript----面向对象编程

TypeScript----面向对象编程

类和对象

​ 首先,在讲解类和对象之前,先举这样一个例子:

​ 建造车:1.画图纸,定义车的特征以及车的功能。2.根据车的图纸来造车

​ 创建对象:1.定义类,定义类的属性及方法。 2.根据定义的类来创造对象

//举个例子:
class Bench{
    //颜色(属性)
    color = 'white';
    //最高速度(属性)
    maxSpeed = 220;
    //驾驶(方法)
    dirve(){
        console.log('run');
    }
    //鸣笛(方法)
    honk = () =>{
       console.log('滴~滴滴~-')
    }
}

const bench = new Bench();
console.log(bench)
console.log(bench.color)
console.log(bench.maxSpeed)
bench.drive()
bench.honk()

通过一家造车厂可以批量生产出很多特征功能一样的汽车,而对象的创建也是如此,可以通过一个类创建多个相同的实物对象,这样的实物对象被称为实例对象

构造函数

构造函数是用来为对象赋予初始值或者执行初始化操作,构造函数名称只能使用constructor

class Bench{
    constructor(){}
}

当使用new关键字创建对象时,可以传递参数,将想要赋予给对象的初始值传递到类的内部,而参数值一般就是对象中某个属性的初始值

class Bench{
    constructor (color:string,maxSpeed:number){}
}
const bench = new Bench('red',220)

在构造函数中,this指向的时通过类创建出来的对象,所以可以通过this来点出对象中的属性,再对属性进行赋值。

class Bench{
    color:string;
    maxSpeed:number;
    
    constructor(color:string,maxSpeed:number){
        this.color = color;
        this.maxSpeed = maxSpeed;
    }
}
const bench = new Bench('red',220)

只读属性

只读属性,如其名,只读属性一旦被赋值,那么这个值就不能被更改。

可以再类中通过 readonly修饰符来讲类的属性设置为只读。

class Bench{
    readonly color:string;
    constructor(color:string){
        this.color = color;
    }
    change(){
        this.color = 'red'
    }
}
const bench = new Bench('red')
//写到这里你会发现color的值不可被更改

继承

​ 在面向对象编程中很多对象都会有相同的属性和方法,这样会导致程序中出现大量的重复性代码。

​ 为此我们可以通过定义一个总类,然后将总类上有的属性和方法继承下去,这样程序中就不会出现大量的重复性代码了而且还可以再具体类中定义独有的属性和方法

class Animal{}
class Dog extends Animal {}
class Cat extends Animal {}

在上述代码中,Animal被称为父类,而Dog和Cat被称为子类。

具体举例:

class Animal {
    eat(){
        console.log('eat')
    }
}
class Cat extends Animal {
    name = 'Tom'
}
class Dog extends Animal {
    name = 'Kate'
}
let cat = new Cat();
cat.eat()
//eat
console.log(cat.name)
//Tom
let dog = new Dog()
dog.eat()
//eat
console.log(dog.name)
//kate

当子类继承了父类之后,若父类需要在初始化时传递参数,由子类接收,在子类的构造函数中通过super条约父类将参数传递给父类

class Animal{
    constructor(public name :string){}
}
class Cat extends Animal {
    old:number
    constructor(old:number,name:string){
        super(name);
        this.old = old
    }
}
const cat = new Cat(1,'Tom')
console.log(cat.old)
//1
console.log(cat.name)
//Tom

子类在继承父类之后,还可以通过重写父类方法对功能进行扩展:

class Animal{
    run(){
        console.log('run');
    }
}
class Cat extends Animal{
    override run(){
        console.log("running");
        super.walk();
    }
}
const cat = new Cat();
cat.run()
//running

访问权限修饰符

通过访问权限修饰符可以只读类中的属性和方法,决定了它们能够在拿一些范围内被访问

修饰符作用
public被 public 关键字修饰的类属性和类方法可以在任何地方使用 (当前类、子类、实例对象)
private被 private 关键字修饰的类属性和类方法只能在当前类中使用
protected被 protected 关键字修饰的类属性和类方法可以在当前类和子类中使用
  • public 公开的 ( 可省略 )
class Animal{
    constructor(){
        this.run();
    }
    public run(){
        console.log('run');
    }
}
class Cat extends Animal{
    run(){
        super.run();
    }
}
const cat = new Cat();
cat.run();
  • private(私有的)
class Animal{
    constructor(){
        this.run()
    }
    private run(){
        console.log('run');
    }
}
class Cat extends Animal{
 //在这里会飘红报错,因为run是私有属性,只能在Animal类中访问
    run(){
        super.run()
    }
}
const animal = new Animal();
//这里也会报错,因为run是Animal的私有属性,只能在Animal类中访问
animal.run()

  • protected 受保护的
class Animal{
    constructor(){
        this.run()
    }
    protected run(){
        console.log('run');
    }
}
class Cat extends Animal{
    run(){
        super.run();
    }
}
const animal = new Aniaml();
//此处会飘红报错,因为run属性受保护,只能在Animal及其子类中访问
animal.dirve()

Getter \ Setter

Getter 和 Setter 是对属性的获取和设置进行封装,获取属性用Getter,修改属性值用Setter

class Animal{
 	private _salary:number;
    constructor(salary:number){
        this._salary = salaery;
    }
    get salary(){
        return this._salary;
    }
    set salary(salary:number){
        this._salary = salary;
    }
}
const animal = new Animal(4000);
console.log(animal.salary);
//识别到获取数据,调用get
animal.salary = 6000;
//识别到更改数据,调用set
console.log(animal.salary);
//识别到获取数据,调用get

索引签名

在JavaScript中,可以为对象动态添加属性,但是在Typescript中这样是不被允许的,因为Typescript对于对象是有严格要求的类型限制

let person = {}
person.name = "张三";
//此时会报错,提示person对象中没用属性名name

那么如何在TypeScript中为对象动态添加属性呢?这就需要用到索引签名了,它可以在不确定属性名称的情况下限制属性的类型以及对象的类型

由于不确定属性名称,所以我们可以为对象动态添加任意符合要求类型的属性。

class Person{
	[str:string]:string;
}
let person = new Person();
person.name1 = '张三';
person.name2 = '李四';

person[true] = 'hello'
//以上会飘红,因为true不能作为索引类型使用
person.name3 = 200;
//以上也会飘红报错,因为在Person中以及定义了字符串类型,所以这个属性不能为数字类型
person[0] = '王五'

静态成员

静态成员是指在类中被static关键字修饰的类属性和类方法,而静态成员属于类,所以可以用类名点出静态成员来进行访问

class Person{
    static name : string = '张三';
}
Person.name;
//类名.静态成员

注意:!!!不能使用实例对象来点出静态成员!!!

用途: 一般来说,静态成员对于该类的任何一个对象而言,可以被当做一个公共的存储单元,该类的任何对象访问它时,不管是获取还是修改,都是在一个单元内进行操作,使用静态属性主要用于各个对象间的数据共享

class Person{
    private static _count :number = 0;
    contructor(){
        Person._count++;
    }
    getCount(){
        return Person._count;
    }
}
const p1 = new Person();
const p2 = new Person();

console.log(p1.getCount());
console.log(p2.getCount());

要记住,静态成员一直存在于内存,而非静态成员要通过实例化才能分配到内存,使用静态成员不能访问非静态成员,但非静态成员可以访问类中的静态成员

class Person{
    private static _count:number=0;
    static fn(){
        this.getCount
        //这里会报错,因为静态成员不能访问非静态成员
        //this指向的是类,而不是类实例
    }
    getCount(){
        return Person._count
        //非静态可以访问静态
    }
}

抽象类

抽象类因继承而存在,通过抽象类可以约束子类必须实现那些成员,通俗来讲,抽象类就是为了继承而存在

在抽象类中可以只定义成员,具体的成员实现由子类完成且必须完成,使用抽象类不能被直接实例化

抽象类由abstract来定义

abstract class Animal {
    abstract color : string;
    abstract render():void;
}
class Cat extends Animal{
    constructor(public color : string){
        super();
    }
    override render():void{
        console.log("render");
    }
}
const cat = new Cat();
console.log(cat.color);
cat.render()

接口

接口,一般用于声明类型,用于对复杂的数据结构进行类型描述比如对象和函数以及类

接口的基本使用

接口声明需要使用interface关键字

使用接口约束对象的类型

interface User{
    name:string;
    age:number;
}
const user:User = {
    name:'张三';
    age:20;
};

使用接口约束函数类型

interface Sum{
    (a:number.m:number):number;
}
const sun:Sum = function(a.b){
    return a+b;
};

使用接口约束类的成员

interface Person {
    name:string;
    addEvent():void;
    removeEvent():void;
}
class NewPerson implements Person{
    name:string = 'test';
    addEvent():void{}
    removeEvent():void{
        
    }
}   
宽松的接口检查

TypeScript 接口检查时宽松的, 当变量满足了接口规范以后,几十遍了中存在接口范围以外的属性也是可以的。

interface User{
    name:string;
    age:number;
}
let user:User = {
    name:'张三',
    age:20,
};
let someone = {
    name:'李四',
    age:50,
    sex:'男',
};
user = someone;
interface Reportable{
    summary():void;
}
function printSummary(item:Reportable):void{
    item.summary()
}

const person = {
    name:'张三',
    summary(){
        console.log(`hello,my name is ${this.name}`);
    },
};
printSummary(person);

对于宽松的接口检查政策字面量是个例外,也就是说对于字面量的接口类型检查还是严格的,不能出现接口以外的其他属性。

interface User {
    name:string;
    age:number;
}
const user : User = {name:'张三',age:20};
const another : User = {name:'李四',age:40,sex:'男'}//此处会报错,因为接口内没有sex
interface Reportable{
    summary():void;
}
function printSummary(item:Reportable):void{
    item.summary();
}
printSummary({
    name:'张三',
    //此处会报错,name 不在类型Reportable中,对象字面量只能指定已知属性
    summary(){
        console.log(`hello,my name is ${this.name}`)
    },
});

绕过严格类型检查模式:

  • 类型断言
interface User{
    name:string;
    age:number;
}
const another : User = {name:'李四',age:40,sex:'男'} as User;
  • 索引签名
interface User{
    name:string;
    age:number;
    [key:string]:string | number;
}
const another : User = {name:'李四',age:40,sex:'男'}
接口继承

接口具有继承特性 接口与接口直接可以存在继承关系,而且一个接口可以继承多个接口

interface Sizes{
     sizes:string[];
     getSize():string[];
}
interface Shape{
    color:string;
}
//Pizza 继承了两个接口,Sizes 以及 Shape
interface Pizza extends Sizes,Shap{
    name:string;
}
let pizza:Pizza = {
    name:'张三',
    color:'skyblue',
    sizes:['large','small'],
    getSize(){
        return this.sizes;
    },
};

在继承了接口以后可以对被继承接口中的属性进行重写,但是重写的类型一定要在原有类型的范围以内。

interface User{
    name:any;
    age:number;
}
interface MyUser extends User{
    name:bollean;
}
接口合并

接口具有声明合并特性 多个相同名称接口会自动合并

interface User {
 	height:number;
    width:number;
}
interface User{
    scale:number;
}
let user:User = {height:5,width:6,scale:10};
interface与 type

在TypeScript中,type可以定义对象、联合类型、基本数据类型,而interface只能定义对象类型。

// ISBN: 国际标准书号
type ISBN = number | string;
type PublicationT = {
    isbn:ISBN;
    another:string;
    publisher:string;
}
interface PublicationI{
    isbn:ISBN;
    author:string;
    publisher:string;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue-cli是一个官方推出的Vue项目脚手架工具,用于快速搭Vue项目。ts是TypeScript的简称,是一种由微软开发的开源编程语言,它是JavaScript的超集,可以为JavaScript代码添加静态类型检查和封装类、模块等面向对象编程的特性。antd是蚂蚁金服开源的一套基于React封装的UI组件库,提供了丰富的高质量的React组件。 将这三者结合在一起,意味着我们可以利用Vue-cli搭一个基于Vue和TypeScript的项目,并使用antd组件库来构界面。这样的项目结合了Vue的简洁、易用和高效性能,TypeScript的类型检查和面向对象编程特性,以及antd的高质量UI组件,可以提升开发效率和代码质量。 在使用Vue-cli创项目时,可以选择使用TypeScript作为项目的开发语言,这样项目就会自动集成TypeScript的相关配置和支持。通过使用Vue-cli提供的命令和配置,我们可以快速搭一个工程化的项目结构,并集成Webpack等构工具。 在项目中使用antd组件库时,可以通过npm或者yarn安装antd包,然后在Vue的组件中引入所需的组件,并进行相关配置和使用。antd提供了丰富的UI组件,包括按钮、表单、弹窗、表格等常见的界面元素,可以根据项目需求进行选择和使用。 在使用TypeScript编写Vue项目时,可以利用TypeScript的静态类型检查、类型提示功能,提升代码的可读性和可维护性。同时,可以使用面向对象的编程方式来组织代码,更好地管理和封装组件、模块等。 综上所述,使用Vue-cli搭一个基于Vue、TypeScript和antd的项目,可以充分发挥各自的优势,提升开发效率和代码质量,同时能够满足丰富的UI界面需求。这样的项目具备良好的可扩展性和可维护性,适合于中大型前端项目的开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值