/**
* 通过联合类型有两个缺点
* 1.进行很多的逻辑判断(类型缩小)
* 2.返回值的类型依然是不能确定的
*/
function add(a1: number | string, a2: number | string) {
if (typeof a1 === "number" && typeof a2 === "number") {
return a1 + a2;
} else if (a1 === "string" && typeof a2 === "string") {
return a1 + a2;
}
}
add(10, 20);
// 函数的重载: 函数的名称相同 但是参数不同的几个函数, 就是函数重载
// 参数不同有两种: 一种是个数不同, 一种是种类不同
function add2(num1: number, num2: number): number; // 没有函数的实现体
function add2(num1: string, num2: string): string;
function add2(num1: any, num2: any): any {
// 具体实现在这里
if (typeof num1 === "string" && typeof num2 === "string") {
return num1.length + num2.length;
}
return num1 + num2;
}
const result1 = add2(20, 30);
const result2 = add2("abc", "cbs");
// 在函数的重载中 实现函数是不能被调用的
// add2({name: 'why'}, {age: 18})
// 函数的重载练习
// 实现方式一:联合类型实现
function getLength(args: string | any[]) {
return args.length;
}
console.log(getLength("dfghhj"));
console.log(getLength([123, 321, 231]));
// 实现方式二:函数的重载
function getLength2(args: string): number;
function getLength2(args: any[]): number;
function getLength2(args: any): number {
return args.length;
}
console.log(getLength2("dfghhj"));
console.log(getLength2([123, 321, 231]));
// 认识类的使用
// 编程范式: 面向对象编程:C++、Java 函数式编程:JavaScript、lisp
// class Person2 {
// name: string = ''
// age: number = 0
// eating() {
// console.log(this.name + 'eating');
// }
// }
// 类的定义
class Person2 {
name: string;
age: number;
eating() {
console.log(this.name + "eating");
}
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
const p = new Person2("why", 18);
console.log(p.name);
console.log(p.age);
p.eating();
// 类的继承1
class Person3 {
name: string = "";
age: number = 0;
eating() {
console.log("eating");
}
}
class Student extends Person3 {
sno: number = 0;
study() {
console.log("studing");
}
}
class Teacher extends Person3 {
title: string = "";
teaching() {
console.log("teaching");
}
}
const stu = new Student()
stu.name = 'coder'
stu.age = 10
console.log(stu.name);
console.log(stu.age);
// 继承2
class Person4 {
name: string
age: number
eating() {
console.log("eating");
}
}
class Student2 extends Person4 {
sno: number
constructor(name: string, age: number, sno: number){
super()
this.sno = sno
}
// 重写父类里面的方法
eating(): void {
console.log('ioiooo');
}
study() {
console.log("studing");
}
}
const stu2 = new Student2('张三', 18, 110)
console.log(stu2.name);
console.log(stu2.age);
console.log(stu2.study);
// 类的多态
class Animal {
action() {
console.log('animal running');
}
}
class Dog extends Animal{
action(): void {
console.log('dog running!!!');
}
}
class Fish extends Animal {
action(): void {
console.log('fish swimming');
}
}
function makeActions(animals: Animal[]) {
animals.forEach(animals=> {
animals.action() // 会执行重写之后的方法
})
}
makeActions([new Dog(), new Fish()])
// 父类引用(类型)指向子类对象 继承十多态的前提
// 多态的目的是为了写出更加具备通用性的代码
// 类的成员修饰符 public private protected
class Person5 {
// public 在任何地方都可以访问 共有的属性或方法 默认的就是public的
public name: string = ''
private age: number = 0
// protected:在类内部和子类中可以访问
protected sno: number = 11
// 封装了两个方法 通过方法来访问name
getAge() {
return this.age
}
setAge(newAge) {
this.age = newAge
}
}
const p2 = new Person5()
console.log(p2.name);
console.log(p2.getAge);
p2.setAge(99)
class Person33 {
// protected:在类内部和子类中可以访问
protected name: string = ""
}
class Student3 extends Person33 {
getName() {
return this.name
}
}
const pp = new Student3()
console.log(pp.getName());
// 只读属性 readonly
class Persona {
// readonly name: string = '123'
// 只读属性一般在constructor里面赋值是比较多的
// 只读属性是可以在构造器里面赋值的
// 属性本身不能进行修改 对象中的属性是可以修改的
readonly name: string
age?: number
readonly friend?: Persona
constructor(name: string, friend?: Persona) {
this.name = name
this.friend = friend
}
}
const pa = new Persona('历史', new Persona('kobe'))
console.log(pa.name);
console.log(pa.friend);
// 取值的时候可以用可选链 修改的时候不行
if(pa.friend) {
pa.friend.age = 18
}
// getter和setter
class Personb {
private name: string
constructor(name: string){
this._name = name
}
// 访问器 getter和setter
// setter
set _name(newName) {
this._name = newName
}
// getter
get _name(){
return this._name
}
}
const pb = new Personb('why')
console.log(pb._name);
pb._name = "123"
// 类的静态成员
// class Persionc {
// name: string = ''
// age: number = 12
// }
// const pc = new Persionc()
// pc.name = '123'
class Studenta {
static time: string = "20:00"
static attendClass(){
console.log('去学习');
}
}
console.log(Studenta.time); // 静态属性可以直接通过类来访问
Studenta.attendClass()
// 抽象类 abstract
function makeArea(shape: Shape){
return shape.getArea()
}
// makeArea('矩形')
// makeArea('圆形')
// 抽象函数可以没有实现体 抽象函数必须在抽象类里面 抽象类不能被实例化
abstract class Shape {
abstract getArea()
}
class Rectangle{
private width:number
private height:number
constructor(width: number, height:number) {
this.width = width
this.height = height
}
getArea() {
return this.width * this.height
}
}
const recttangle = new Rectangle(20, 30)
// 类的类型
class Persond {
name: string = '123'
eating() {}
}
const pd = new Persond()
const p1: Persond = {
name: '999',
eating(){}
}
function printPerson(p: Persond){
console.log(p.name);
}
printPerson(new Persond)
printPerson({
name: '000',
eating(){}
})