TS中的面向对象
面向对象是程序中一个非常重要的思想,它被很多同学理解成了一个比较难,比较深奥的问题,其实不然。面向对象很简单,简而言之就是程序之中所有的操作都需要通过对象来完成。
操作浏览器要使用window对象
操作网页要使用document对象
操作控制台要使用console对象
一切操作都要通过对象,也就是所谓的面向对象,那么对象到底是什么呢?
计算机程序的本质就是对现实事物的抽象,抽象的反义词是具体,比如:照片是对一个具体的人的抽象,汽车模型是对具体汽车的抽象等等。程序也是对事物的抽象,在程序中我们可以表示一颗花生米,一个炸弹等等所有的事物。一个事物到了程序中就变成了一个对象。在程序中所有的对象都被分成了两个部分数据和功能,以人为例,人的姓名、性别、年龄、身高、体重等属于数据,人可以说话、走路吃饭、睡觉这些属于人的功能。数据在对象中被成为属性,而功能就被称为方法。所以简而言之,在程序中一切皆是对象。
1,类 (class)
要想面向对象,操作对象,首先便要拥有对象,那么下一个问题就是如何创建对象。要创建对象,必须要先定义类,所谓的类可以理解为对象的模型,程序中可以根据类建指定类型的对象,举例来说: 可以通过Person类来创建人的对象,通过Dog类创建狗的对象,通过Cat类来创建猫的对象,不同的类可以用来创建不同的对象。
// 使用关键字class定义一个类
/*
* 对象中包含两个东西,一个是属性一个是方法
* */
class Person {
// 定义实例属性(该属性存到person实例身上的,只有new了实例才能使用实例属性)
name:string="山鱼"
// 在属性前边使用static关键字就可以定义类属性
static age:number=12
// readonly 只读属性
readonly gender:string = "男"
// 定义一个方法
sayGoodBay(){
console.log('BayBay')
}
// 定义一个类方法
static sayHello(){
console.log('HELLO')
}
}
var psn = new Person();
console.log(psn);
// 访问静态属性直接使用类访问即可
console.log(Person.age);
psn.sayGoodBay();
Person.sayHello();
2,构造函数&this
class Bolog {
name:string
age:number
constructor(name:string,age:number) {
this.name=name
this.age=age
}
wolf(){
// 这里的this表示当前调用的方法的this
console.log(this.name)
}
}
const dog = new Bolog('来福',2);
const dog2 = new Bolog('元宝',3);
console.log(dog)
dog.wolf();
dog2.wolf();
3,继承
Animal被称为父类,Dog,Cat被称为子类使用继承后,子类将会拥有父类所有的方法和属性通过继承可以将多个类中共有的代码写在一个父类中,这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法如果希望在子类中添加一些父类中没有的质性或方法直接加就行如果在子类中添加了和父类相同的方江,则于类方法会覆盖掉父类的方法,子类的方法覆盖掉父类的方法这种行为被称为重写
(function () {
class Animal {
name:string
age:number
cora:string
constructor(name:string,age:number,cora:string) {
this.name=name
this.age=age
this.cora=cora
}
hello(){
console.log(this.cora)
}
}
// 使用extends完成继承操作
// 使Dog继承Animal
class Dog extends Animal{
// 在继承Animal类所有的功能情况下还可以在自己添加其他的功能
run(){
console.log(`${this.name}在跑~~~`)
}
}
// 使Cat继承Animal
class Cat extends Animal{
}
const dog = new Dog('小宝',2,'wowowo')
console.log(dog)
dog.hello();
dog.run();
const cat = new Cat('小米',3,'mimimi')
console.log(cat)
cat.hello()
})()
4,super
(function () {
class Person {
name:string
constructor(name:string) {
this.name=name
}
sayHello(){
console.log('大家好')
}
}
class Xiaoming extends Person{
// 在类的方法中super就相等于父类的实例
// 如果在子类中写了构造函数,在子类构造函数中必须调用父类的属性
constructor(name:string,age:number) {
super(name);
}
sayHello(){
super.sayHello()
}
}
const xiaoming = new Xiaoming('小明',3);
xiaoming.sayHello()
})()
5,抽象类
以abstract开头的类是抽象类抽象类和其他类区别不大,只是不能用来创建对象简单来说抽象类就是用来被继承的类抽象类中可以添加抽象方法
(function () {
abstract class Person {
name:string
constructor(name:string) {
this.name=name
}
// 定义一个抽象方法抽象方法使用 abstract开头,没有方法体抽象方法只能定义在抽象类中, //子类必须对抽象方法进行重写
abstract sayHello():void
}
class Xiaoming extends Person{
// 在类的方法中super就相等于父类的实例
// 如果在子类中写了构造函数,在子类构造函数中必须调用父类的属性
sayHello(){
console.log(123)
}
}
const xiaoming = new Xiaoming('小明');
xiaoming.sayHello()
})()
6,接口
使用接口定义一个类的结构,用来定义一个类中应该包含那些属性和方法同时接口也可以当成类型声明去使用接口可以在定义类的时候去限制类的结构接口中的所有的属性都不能有实际的值接口只定义对象的结构,而不考虑实际值在接口中所有的方法都是抽象方法定义类时,可以使类去实现一个接口,实现接口就是使类满足接口的要求简而言之,接口就是一个规范,当满足接口条件的时候才会触发某些行为
(function (){
// 定义一个对象的类型
type inte = {
name:string
age:number
}
// 定义一个接口
interface MyinterFace{
name:string
age:number
sayHello():void
}
class Person implements MyinterFace{
age: number;
name: string;
constructor(name:string,age:number) {
this.name=name
this.age = age
}
sayHello(): void {
}
}
// const obj:inte={
// name:'Shanyu',
// age:2
// }
// const obj2:MyinterFace={
// name:'Shanyu2',
// age:3
// }
})()
7,属性的封装
当一个属性被封装以后,只能通过方法进行从外部修改。TS可以在属性前添加属性的修饰符
public修饰的属性可以在任意位置访问(修改) 默认值
private私有属性,私有属性只能在美内部进行访问(修改)
protected受包含的属性,只能在当前类和当前类的子类中访问、修改
(function () {
class Person {
private name:string
private age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
// getName(){
// return this.name
// }
// setName(value:string){
// this.name=value
// }
// TS中设置get,set方法的方式
get name1 (){
return this.name
}
set name1(value){
this.name=value
}
}
// 现在属性是在对象中设置的,属性可以任意的被修改属性可以任意被修改将会导致对象中的数据交得非常不安全
const per = new Person('山鱼',33)
// console.log(per.getName())
// per.setName('小沙弟')
// console.log(per)
console.log(per.name1)
per.name1 = "oaosj"
console.log(per.name1)
})()
8,泛型
在定义函数或者是类时,如果遇到类型不明确就可以使用泛型
在ts中可以定义多个泛型,也可以用接口给泛型指定一个范围
// function f(a:number):number{
// return a
// }
// 定义一个泛型
functionf1<S>(a:S):S{
returna
}
// 不指定泛型TS自动对类型进行判断
f1(10)
// 还可以对泛型进行指定
f1<string>("1")
// 也可以指定多个泛型
functionf2<T,A>(a:T,b:A):T {
returna
console.log(b)
}
f2(2,"b")
// 也可以给泛型指定一个接口来限制他的范围
interface Inter{
length:number
}
// <A extends Inter表示泛型A必须是Inter的实现类
functionsy<AextendsInter>(a:A):number {
return a.length
}
sy({length:10})
sy("20")
点赞:您的赞赏是我前进的动力! 👍
收藏:您的支持我是创作的源泉! ⭐
评论:您的建议是我改进的良药! ✍
山鱼的个人社区:欢迎大家加入我的个人社区—— 山鱼社区