啊啊啊啊啊真的会谢!和后端拿一个数据,问半天为什么要这个数据
言归正传!我!终于看懂了三年前没有学懂的面向对象了
ts是个好东西啊兄弟们
类:
- 实例属性:直接定义,需要通过实例进行访问的
- 类属性(静态属性):
static
直接通过类访问 - 只读属性:
readonly
不能改 - public(默认) :属性可以在任意位置访问(修改)
private: 私有属性,只能在类内部进行访问修改,不被子类访问
protect: 保护属性,只能在当前类和子类中使用
class Person{
// 直接定义的为实例属性,要通过实例进行访问
name: string = '孙悟空';
// 在属性前使用static可以定义类属性(静态属性)
static age: number = 18;
// readonly:只读属性,不可修改
readonly gender: number = 0;
// 定义方法(使用static可以定义类方法)
sayHello(){
console.log("say hello");
}
}
const per = new Person();
console.log(per);//Person {name: '孙悟空'}
console.log(Person.age);//18
// per.gender = 1;//报错
// 方法
per.sayHello()
构造函数:可以实现动态赋值
constructor
:在创建对象时被调用this
:指向构建的对象的属性(class的属性)
class Dog{
name = '旺财';
age = 3;
bark(){
alert('wwww')
}
// 构造函数: 在创建对象时被调用
constructor(name: string, age: number){
// this指向构建的对象中的属性
this.name = name,
this.age = age
}
}
const dog = new Dog("小黄", 1);
const dog1 = new Dog("小花", 2);
const dog2 = new Dog("大黄", 18);
console.log(dog);
console.log(dog1);
console.log(dog2);
//Dog {name: '小黄', age: 1}
//Dog {name: '小花', age: 2}
//Dog {name: '大黄', age: 18}
继承: 将几个拥有共同属性,共同方法(功能)的类合并在一起,只写一次,再进行个性化修改
- 子类中写父类的方法名的方法,叫做
重写
super
为父类对象,可以获取父类的属性方法等- 当子类有
新增的属性
,需要用到constructor
进行构造,此时需要引入父类的属性
(function(){
class Animal{
name: string | undefined;
age: number | undefined;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
sayHello(){
console.log('父类:动物在叫');
}
}
// extends: 继承
// 子类(Dog)继承父类(Animal)
// 子类拥有父类所有的方法和属性
// 作用:将多个类中共有的代码统一写在父类中
//super为父类对象
class Dog extends Animal{
gender: number | undefined;
constructor(name: string, age: number, gender: number){
super(name, age);
this.gender = gender;
}
run(){//属于当前子类自己的方法
console.log(`${this.name}在跑`);
}
sayHello() {//重写父类方法
console.log('子类:狗子叫');
super.sayHello();
}
}
const dog = new Dog('狗子', 5, 0)
console.log(dog);
dog.sayHello();
dog.run();
})()
抽象类:父类不能被直接使用,是一个抽象化的存在,没有实质性的功能,只能被继承
abstract
:不能用于创建实例,只能被继承- 在
抽象类
中可以定义抽象方法
,继承者必须重写
该方法
(function(){
// abstract :抽象类
// 不能用于创建对象(new CLASS())
// 只是用来被继承(只能当爸爸)
abstract class Animal{
name: string | undefined;
age: number | undefined;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
// 可以添加抽象方法 ,同样只能被重写,不能直接被调用
// 只能被定义在抽象类中
// 继承类者必须重写改方法
abstract sayHello():void;
}
class Dog extends Animal{
sayHello() {
console.log('子类:狗子叫');
}
}
const dog = new Dog('狗子', 5)
console.log(dog);
dog.sayHello();
})()
接口:用来定义一个类的规范(模板),是一种规范化的存在
- 可以多次定义,最终进行合并(???有点怪,感觉有坑)
- 里面的所有属性没有实际的值(函数==抽象函数)
(function(){
type myType = {
name: string,
age: number
}
// 接口:用来定义一个类的规范(模板)
// 可以多次定义,最终进行合并(???有点怪,感觉有坑)
interface myInterface{
name: string,
age: number
}
interface myInterface{
gender: number
}
const obj: myInterface = {
name: '11',
age: 88,
gender: 0
}
// 接口可以限制类的结构
// 里面的所有属性没有实际的值(函数==抽象函数)
interface MyInter{
name: string;
sayHello():void;
}
class MyClass implements MyInter{
name: string;
constructor(name: string){
this.name = name;
}
sayHello(){
console.log("大家好");
}
}
})()
属性封装:可以做到拦截修改,提高安全性
- ts中自己封装了getter和setter的方法,在需要进行修改拦截(年龄问题)的情况下可以进行使用
(function(){
class Person{
// public(默认) :属性可以在任意位置访问(修改)
// private: 私有属性,只能在类内部进行访问修改,可以做到拦截修改(set,get)
// - 私有熟悉不被子类访问
// protect: 保护属性,只能在当前类和子类中使用
private _name: string;
private _age: number;
constructor(name:string, age: number){
this._name= name;
this._age = age;
}
get age(){
return this._age;
}
//=================原理
// getAge(){
// return this._age;
// }
set age(value: number){
if(value < 0 || value > 200){
throw new Error("age不合法");
}
this._age = value
}
//==================原理
// setAge(value:number){
// if(value < 0 || value > 200){
// throw new Error("age不合法");
// }
// this._age = value;
// }
}
const per = new Person('孙悟空', 18);
per.age = 100
console.log(per.age);//100
})()
泛型:对不确定类型的参数进行变量定义,调用时再指定
// 定义函数/类时,遇到类型不明确时可以使用泛型
// T为类型的变量,调用时才赋值
function fn<T>(a:T): T{
return a;
}
console.log(fn(10));//不指定泛型,TS自动对类型进行推断
console.log(fn<string>('hello'));//指定泛型
function fn2<T,K>(a:T, b:K):T{
console.log(b);
return a;
}
interface Inter{
length: number;
}
// T 要实现Inter接口(拥有length属性:字符串、obj.length)
function fn3<T extends Inter>(a: T): number{
return a.length;
}
fn3('123');
fn3({length: 7})
我第一次接触ts,因为不理解ts使用的意义比如说接口,结果全程把ts当js写
其实对于ts的意义,在学习理解了面向对象的思想之后,倒是有点清楚了。
到最后老师说了,这个东西并不是说一定要用,但是他是一种规范,一种思想。
虽然有些配置和操作确实比起js来说复杂不少,但是不得不说,统一开发规范可见地会大大地有利于后期维护以及多人的合作开发
如果你还是有点不理解ts到底用来干嘛,建议花点时间看看这几个视频