TypeScript(三)对象,接口,类,泛型

news/2024/4/24 17:16:22/文章来源:https://blog.csdn.net/chengcheng9876/article/details/136374633

一、 对象

Typescript 中 Object 类型不单是指普通对象类型,它泛指所有的非原始类型,也就是对象,数组还有函数。
普通对象就是键值对的集合,我们可以使用接口来定义对象的结构。
	interface Person { // Person是接口CHname: string;age: number;className: string;}let personInfo: Person = {CHname: "迪西",age: 10,className: '三年级',};console.log(personInfo); // {CHname: '迪西', age: 10, className: '三年级'}
  1. 对象解构赋值
    TypeScript 支持对象解构赋值,让我们能够更便捷地从对象中提取值并赋给变量。
    let {age, CHname } = personInfo; // 将age和CHname 属性,分别复制给age和CHname
    console.log(CHname ); // 迪西
    console.log(age); // 10
    
  2. 对象展开运算符

    对象展开运算符 (…) 允许我们将一个对象的属性展开到另一个对象中,并创建一个新的对象。

    let addressInfo = {city: '天津',schoolName: '第三实验小学',
    }let info = {...personInfo, ...addressInfo};
    console.log(info); // {CHname: '迪西', age: 10, className: '三年级', city: '天津', schoolName: '第三实验小学'}
    // 用展开运算符 (...)将personInfo对象和addressInfo对象的属性添加到info 对象中,info 未新对象
    
  3. 对象类型断言
    有时候需要告诉 TypeScript 某个对象的类型,可以使用类型断言。
    let unknownPerson: any = { CHname: "丁丁", age: 12 };
    let typedPersonInfo = unknownPerson as Person;
    console.log(typedPersonInfo); // {CHname: '丁丁', age: 12
    
  4. 深层对象属性
    当对象包含嵌套结构时,通过点操作符,我们可以访问深层对象的属性。
    interface Person {CHname: string;age?: number;className?: string;address: Address;
    }interface Address {cityCHname: string;schoolName: string;
    }let personInfo: Person = {CHname: "迪西",address: { cityCHname: "天津", schoolName: "第三实验小学" },
    };
    console.log(personInfo.address.cityCHname); // 天津
    
  5. 对象的方法
    方法是与对象相关联的函数。
    interface Person {CHname: string;age?: number;className?: string;bark(): void;
    }
    let personInfo: Person = {CHname: "迪西",bark(){console.log('Hello')}
    };
    personInfo.bark(); // Hello
    

二、 接口

可以理解为一种规范或者契约,它可以用来约定对象的结构,我们去使用一个接口就要去遵循这个接口的所有约定。在 typescript 中,接口最直观的体现是,约定一个对象当中具体应该有那些成员,并且这些成员是什么类型的。
编译之后,没有任何有关接口的代码,其实 typescript 的接口只是为我们**有结构的数据做类型约束,在运行阶段这种接口没有意义**。
  1. 基本用法
    接口是一种抽象的数据类型,定义了对象的结构,包括属性类型和方法。

    interface Person {CHname: string;age: number;
    }function greet(person: Person): string {return `${person.CHname} ${person.age}`;
    }
    console.log(greet({CHname: '迪西', age: 10})); // 迪西 10
    

    编译之后

    	function greet(person) {return "".concat(person.CHname, " ").concat(person.age);
    }
    console.log(greet({ CHname: '迪西', age: 10 }));
    
  2. 可选属性
    在 TypeScript 中,我们可以通过在属性后面加上 ? 来实现,接口中的某些属性是可选的。

    interface User {name: string;age?: number;
    }
    let userInfo1: User = { name: "丁丁" }; // age 是可选的,可以选择在对象赋值时选择添加或者省略。
    let userInfo2: User = { name: "小波", age: 9 };
    
  3. 只读属性
    初始化过后不能再修改,关键字 readonly

    interface Post {title: stringcontent: stringsubtitle?: string // 可选成员readonly summary: string // 只读成员
    }
    const hello: Post = {title: 'hello, typeScript',content: 'a javascript superset',summary: 'a javascript',
    }
    hello.summary = 'typeScript';
    

    在这里插入图片描述

  4. 可索引类型的接口
    接口还可以描述具有索引类型的对象,使我们能够按索引访问对象的属性。

    // StudentArray  表示具有数字索引的字符串数组, 通过索引访问数组元素。
    interface StudentArray {[index: number]: string;
    }
    let myClass: StudentArray;
    myClass = ["迪西", "丁丁"];let student: string = myClass[0];
    console.log(student); // 迪西
    
  5. 接口继承
    接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
    继承关键字:extends,如果继承多个用“逗号”隔开

    interface Shape {color: string;
    }
    interface Square extends Shape { sideLength: number;
    }
    let square = <Square>{};
    square.color = "blue";
    square.sideLength = 10;
    console.log(square); // {color: 'blue', sideLength: 10}
    

    一个接口可以继承多个接口,创建出多个接口的合成接口。

    interface Shape {color: string;
    }
    interface PenStroke {penWidth: number;
    }
    interface Square extends Shape, PenStroke { // 继承多个用“逗号”隔开sideLength: number;
    }
    let square = <Square>{};
    square.color = "blue";
    square.sideLength = 10;
    square.penWidth = 5.0;
    console.log(square); // {color: 'blue', sideLength: 10, penWidth: 5}
    
  6. 混合类型
    接口能够描述JavaScript里丰富的类型。 因为JavaScript其动态灵活的特点,有时你会希望一个对象可以同时具有上面提到的多种类型。
    在使用JavaScript第三方库的时候,你可能需要像上面那样去完整地定义类型

    interface Counter {(start: number): string;interval: number;reset(): void;
    }function getCounter(): Counter {let counter = <Counter>function (start: number) { };counter.interval = 123;counter.reset = function () { };return counter;
    }let c = getCounter();
    c(10);
    c.reset();
    c.interval = 5.0;
    
    interface Counter {(start: number, end: number): string;
    }function getCounter(): Counter {let counter = <Counter>function (start: number, end: number) {console.log(start + end); // 12};return counter
    }
    let c = getCounter();
    c(10, 2);
    
  7. 类实现接口
    TypeScript也能够用它来明确的强制一个类去符合某种契约。
    注:接口描述了类的公共部分,而不是公共和私有两部分。 它不会帮你检查类是否具有某些私有成员。
    关键字 implements

    interface ClockInterface {currentTime: Date;setTime(d: Date): void;}class Clock implements ClockInterface {currentTime: Date = new Date();setTime(nDate: Date): void {this.currentTime = nDate;}}let clock = new Clock();clock.setTime(new Date());console.log(clock.currentTime); // Tue Mar 05 2024 10:57:48 GMT+0800 (中国标准时间)
    
  8. 接口继承类
    当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的private和protected成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。

    当你有一个庞大的继承结构时这很有用,但要指出的是你的代码只在子类拥有特定属性时起作用。 这个子类除了继承至基类外与基类没有任
    何关系。

    class Control {private state: any;
    }interface SelectableControl extends Control {select(): void;
    }
    // SelectableControl包含了Control的所有成员,包括私有成员state。 因为 state是私有成员,所以只能够是Control的子类们才能实现SelectableControl接口,因为只有 Control的子类才能够拥有一个声明于Control的私有成员state,这对私有成员的兼容性是必需的。
    class Button extends Control implements SelectableControl {select() { }
    }class TextBox extends Control {select() { }
    }// 错误:“Image”类型缺少“state”属性。
    class Image implements SelectableControl {select() { }
    }class Location {}
    // 在Control类内部,是允许通过SelectableControl的实例来访问私有成员state的。 实际上, SelectableControl接口和拥有select方法的Control类是一样的。 
    //Button和TextBox类是SelectableControl的子类(因为它们都继承自Control并有select方法),
    //但Image和Location类并不是这样的。
    

三、类

类,面向对象编程的核心,涵盖了类的基本定义、继承、访问修饰符、静态成员与静态方法、类的抽象等方面
使用 class 关键字来定义类。
	class Greeter {greeting: string;constructor(message: string) {this.greeting = message;}greet() {return "Hello, " + this.greeting; // this表示是访问的是类的成员。}}let greeter = new Greeter("world");console.log(greeter); // { greeting: "world" }

类的使用注意点:

  • 直接使用 this 去访问当前类的属性会报错,是因为在 TypeScript 当中,我们要明确在类型当中去声明它所拥有的一些属性,而不是直接在构造函数当中通过 this 动态添加。
    class Person {constructor(name: string, age: number) {this.name = name; // 报错this.age = age; // 报错}
    }
    
    在这里插入图片描述
  • 在 typescript 当中,类的属性必须要有一个初始值,要么在声明的时候通过=号去赋值,要么就在构造函数里初始化。
    class Person {name: string; // 报错age: number; // 报错constructor(name: string, age: number) {// this.name = name;// this.age = age;}
    }
    
    在这里插入图片描述
  1. 类的访问修饰符
    public: 默认为 public

    class Animal {public name: string;public constructor(theName: string) { this.name = theName; }public move(distanceInMeters: number) {console.log(`${this.name} moved ${distanceInMeters}m.`);}
    }
    

    private:不能在声明它的类的外部访问

    class Animal {private name: string;constructor(theName: string) { this.name = theName; }
    }new Animal("Cat").name; // 错误: 'name' 是私有的.
    

    在这里插入图片描述
    带有 private或 protected成员的类型的时候,情况就不同了。 如果其中一个类型里包含一个 private成员,那么只有当另外一个类型中也存在这样一个 private成员, 并且它们都是来自同一处声明时,我们才认为这两个类型是兼容的。 对于 protected成员也使用这个规则。

    class Animal {private name: string;constructor(theName: string) { this.name = theName; }
    }class Rhino extends Animal {constructor() { super("Rhino"); }
    }
    // Rhino是Animal的子类 Animal和 Rhino共享了来自 Animal里的私有成员定义 private name: string,因此它们是兼容的
    class Employee {private name: string;constructor(theName: string) { this.name = theName; }
    }
    // Employee尽管和Animal很像也有私有成员name,但和Animal无关let animal = new Animal("Goat");
    let rhino = new Rhino();
    let employee = new Employee("Bob");animal = rhino;
    animal = employee; // 错误: Animal 与 Employee 不兼容.
    

    在这里插入图片描述
    protected:派生类中仍然可以访问

    class Person {protected name: string;constructor(name: string) { this.name = name; }
    }class Employee extends Person {private age: number;constructor(name: string, age: number) {super(name)this.age = age;}public getElevatorPitch() {return `name: ${this.name}; age ${this.age}.`;}
    }
    let howard = new Employee("迪西", 9);
    console.log(howard.getElevatorPitch());
    console.log(howard.name); // 错误
    

    在这里插入图片描述
    构造函数也可以被标记成 protected。 这意味着这个类不能在包含它的类外被实例化,但是能被继承

    class Person {protected name: string;protected constructor(theName: string) { this.name = theName; }
    }// Employee 能够继承 Person
    class Employee extends Person {private age: number;constructor(name: string, age: number) {super(name);this.age = age;}public getElevatorPitch() {return `Hello, my name is ${this.name} and I work in ${this.age}.`;}
    }	let howard = new Employee("迪西", 9);
    let john = new Person("John"); // 错误: 'Person' 的构造函数是被保护的.
    

    在这里插入图片描述
    readonly: 只读属性必须在声明时或构造函数里被初始化。

    class Octopus {readonly name: string;readonly numberOfLegs: number = 8;constructor (theName: string) {this.name = theName;}
    }
    let dad = new Octopus("Man with the 8 strong legs");
    dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
    

    在这里插入图片描述

  2. 类的构造函数参数属性
    可以在构造函数的参数前面添加访问修饰符,它将自动变成类的成员。

    class Person {constructor(private name: string, public age: number) {}
    }
    // private 关键字,它将 name 参数自动转换为类的私有成员
    // public 关键字,它将 age 参数转换为类的公共成员
    // 相当于在类中声明了 private name: string ,和 public age: number。
    
  3. 参数属性的默认值
    可以为构造函数的参数提供默认值,避免在类外部手动初始化。

    class Car {constructor(public brand: string, public model: string = "BaseModel") {console.log(brand, model); // 比亚迪 BaseModel}
    }
    let carData = new Car('比亚迪')
    
  4. 存取器(Getter 和 Setter)
    使用 get 和 set 关键字,可以定义存取器,允许你在访问或设置属性值时执行额外的逻辑

    class Person {private name: string = '';private age: number = 0;get getAge(): number {return this.age;}set setAge(value: number) {if (value < 6) {throw new Error(this.name + "年龄太小了!");}this.age = value;}
    }
    
  5. 类的继承
    继承是面向对象编程中的重要概念,在 TypeScript 中,我们可以使用 extends 关键字实现类的继承。

    class Animal {move(distanceInMeters: number = 0) {console.log(`Animal moved ${distanceInMeters}m.`);}
    }
    class Dog extends Animal {bark() {console.log('Woof! Woof!');}
    }
    const dog = new Dog();
    dog.bark();
    dog.move(10);
    dog.bark();
    //  Dog是一个 派生类,它派生自 Animal 基类,通过 extends关键字。 派生类通常被称作 子类,基类通常被称作 超类。
    

    以上代码是基础用法,类从基类中继承了属性和方法

    class Animal {name: string;constructor(theName: string) { this.name = theName; }move(distanceInMeters: number = 0) {console.log(`${this.name} moved ${distanceInMeters}m.`);}
    }class Snake extends Animal {constructor(name: string) { super(name); }move(distanceInMeters = 5) {console.log("Slithering...");super.move(distanceInMeters);}
    }class Horse extends Animal {constructor(name: string) { super(name); }move(distanceInMeters = 45) {console.log("Galloping...");super.move(distanceInMeters);}
    }let sam = new Snake("Sammy the Python");
    let tom: Animal = new Horse("Tommy the Palomino");sam.move();
    tom.move(34);
    // 打印结果
    // Slithering...
    // Sammy the Python moved 5m.
    // Galloping...
    // Tommy the Palomino moved 34m.
    // 使用 extends关键字创建了 Animal的两个子类: Horse和 Snake。派生类包含了一个构造函数,它 必须调用 super(),它会执行基类的构造函数
    

    TypeScript强制执行的一条重要规则。在构造函数里访问 this的属性之前,我们 一定要调用 super()

  6. 静态成员与静态方法
    静态成员和静态方法属于类本身,而不是类的实例。它们可以通过类名直接访问,而无需实例化类,适用于不依赖于实例状态的情况。
    使用关键字:static

    class Grid {static origin = {x: 0, y: 0};calculateDistanceFromOrigin(point: {x: number; y: number;}) {let xDist = (point.x - Grid.origin.x);let yDist = (point.y - Grid.origin.y);return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;}constructor (public scale: number) { }
    }let grid1 = new Grid(1.0);  // 1x scale
    let grid2 = new Grid(5.0);  // 5x scaleconsole.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
    console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
    // 用 static定义 origin, 每个实例想要访问这个属性的时候,都要在 origin前面加上类名。 
    // 如同在实例属性上使用 this.前缀来访问属性一样,这里我们使用 Grid.来访问静态属性。
    
  7. 类的抽象
    抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。

    abstract class Animal {abstract makeSound(): void;move(): void {console.log('roaming the earch...');}
    }
    

    抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。 抽象方法的语法与接口方法相似。 两者都是定义方法签名但不包含方法体。 然而,抽象方法必须包含 abstract关键字并且可以包含访问修饰符。

    	abstract class Department {constructor(public name: string) {}printName(): void {console.log('Department name: ' + this.name);}abstract printMeeting(): void; // 必须在派生类中实现
    }class AccountingDepartment extends Department {constructor() {super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()}printMeeting(): void {console.log('The Accounting Department meets each Monday at 10am.');}generateReports(): void {console.log('Generating accounting reports...');}
    }let department: Department; // 允许创建一个对抽象类型的引用
    department = new Department(); // 错误: 不能创建一个抽象类的实例
    department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
    department.printName();
    department.printMeeting();
    department.generateReports(); // 错误: 方法在声明的抽象类中不存在
    

    在这里插入图片描述
    在这里插入图片描述

  8. 抽象静态成员
    可以在抽象类中定义静态成员,派生类可以继承这些静态成员。

    abstract class Animal {static type: string;abstract makeSound(): void;
    }class Dog extends Animal {static type = "Dog";makeSound(): void {console.log("Woof!");}
    }
    
  9. 类与接口
    类与类之间的一些共同点可以用接口去抽象,

    interface EatAndRUn {eat (food: string) : voidrun (distance: number) : void
    }
    // 通过关键字 implements 实现 这个 EatAndRUn 接口
    // 此时这个类必须要有这个接口对应的成员
    class Person implements EatAndRUn{eat (food: string): void {console.log(`优雅的进餐:${food}`)}run (distance: number) {console.log(`直立行走:${distance}`)}
    }class Animal implements EatAndRUn{eat (food: string): void {console.log(`呼噜呼噜的吃:${food}`)}run (distance: number) {console.log(`爬行:${distance}`)}
    }
    

    需要注意的是:在 C# 和 Java 这些语言当中,它建议我们尽可能让每个接口的定义更加简单更加细化,因此我们建议一个接口只去约束一个能力,让一个类同时实现多个接口。

    interface Eat {eat (food: string): void
    }interface Run {run (distance: number): void
    }class Person implements Eat, Run {eat (food: string): void {console.log(`优雅的进餐: ${food}`)}run (distance: number) {console.log(`直立行走: ${distance}`)}
    }class Animal implements Eat, Run {eat (food: string): void {console.log(`呼噜呼噜的吃: ${food}`)}run (distance: number) {console.log(`爬行: ${distance}`)}
    }
    

四、泛型

  1. 泛型基础
    指的是我们去定义函数,接口,类的时候没有去定义具体类型,我们在使用的时候再去定义指定类型的这一种特征。
    能通过泛型编写更通用的代码,摆脱对数据类型的限制。
    泛型就是在我们定义的时候把不明确的类型,变成一个参数,在我们使用的时候再传递这样的一个类型参数。

    function identity<T>(arg: T): T {return arg;
    }
    let output1 = identity<string>("myString");
    let output2 = identity<number>(9);
    
  2. 泛型数组
    Array 是一个泛型类,在 typescript 中去定义这个 Array 类型时,它不知道我们使用它去存放什么样类型的数据,所以它就使用泛型参数,在我们去调用的时候再传入具体类型,这是一个泛型提现。

    function printArray<T>(arr: T[]): void {for (let item of arr) {console.log(item); // 1 2 3 4 5     迪西 丁丁 拉拉 小波}
    }
    let numbers: number[] = [1, 2, 3, 4, 5];
    printArray(numbers);let nameList: string[] = ["迪西", "丁丁", "拉拉", "小波"];
    printArray(nameList);
    
  3. 泛型约束
    对泛型进行一些限制,确保传入的类型拥有某些属性或方法,这就是泛型约束的作用

    let nameList: string[] = ["迪西", "丁丁", "拉拉", "小波"];
    interface Lengthwise {length: number;
    }function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);  //nameList数组的长度 4 传入对象属性length的长度 9return arg;
    }
    // loggingIdentity(3); // 传入的数字没有 length属性
    loggingIdentity(nameList); 
    loggingIdentity({length: 9, value: 3});
    

    在这里插入图片描述

  4. 泛型类
    泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面
    与接口一样,直接把泛型类型放在类后面,可以帮助我们确认类的所有属性都在使用相同的类型。
    类有两部分:静态部分和实例部分。 泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型

    class Box<T> {private content: T;constructor(initialContent: T) {console.log(initialContent); // 42  TypeScriptthis.content = initialContent;}getContent(): T {return this.content;}
    }
    let numberBox = new Box<number>(42);
    console.log(numberBox.getContent()); // 42 TypeScriptlet stringBox = new Box<string>("TypeScript");
    console.log(stringBox.getContent());
    
  5. 泛型与函数重载
    泛型与函数重载结合使用,可以更灵活地处理不同类型的输入。

    function getResult(arg: string): string;
    function getResult(arg: number): number;
    function getResult<T>(arg: T): T {return arg;
    }let resultString: string = getResult("TypeScript");
    let resultNumber: number = getResult(18);console.log(resultString); // TypeScript
    console.log(resultNumber); // 18
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_997036.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python算法题集_搜索插入位置

Python算法题集_搜索插入位置 题51&#xff1a;搜索插入位置1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【二分法查找】2) 改进版一【二分法查找终止条件判断】3) 改进版二【第三方模块】 4. 最优算法5. 相关资源 本文为Python算法题集之一的…

基于springboot的智能物流管理系统论文

智能物流管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了智能物流管理系统的开发全过程。通过分析智能物流管理系统管理的不足&#xff0c;创建了一个计算机管理智能物流管理系统的方案。文章介绍了智…

OpenCV与AI深度学习 | 基于OpenCV实现模糊检测 / 自动对焦

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;基于OpenCV实现模糊检测 / 自动对焦 导 读 本文主要介绍使用OpenCV实现图像模糊检测/相机自动对焦功能。 前 言 为了检测图片是否对焦&…

深入浅出(二)MVVM

MVVM 1. 简介2. 示例 1. 简介 2. 示例 示例下载地址&#xff1a;https://download.csdn.net/download/qq_43572400/88925141 创建C# WPF应用(.NET Framework)工程&#xff0c;WpfApp1 添加程序集 GalaSoft.MvvmLight 创建ViewModel文件夹&#xff0c;并创建MainWindowV…

抖音视频评论批量采集软件|视频下载工具

《轻松搞定&#xff01;视频评论批量采集软件&#xff0c;助您高效工作》 在短视频这个充满活力和创意的平台上&#xff0c;了解用户评论是了解市场和观众心声的重要途径之一。为了帮助您快速获取大量视频评论数据&#xff0c;我们推出了一款操作便捷、功能强大的软件&#xff…

18个惊艳的可视化大屏(第20辑):物联网场景

实时监控和管理 物联网系统通常涉及大量的传感器、设备和数据&#xff0c;通过将这些数据可视化展示在大屏上&#xff0c;可以实时监控和管理物联网系统的运行状态。这有助于及时发现问题、快速响应&#xff0c;并提高系统的可靠性和稳定性。 数据分析和决策支持 可视化大屏可…

Redis小白入门教程

Redis入门教程 1. Redis入门1.1 Redis简介1.2 Redis服务启动与停止1.2.1 Redis下载1.2.2 服务启动命令1.2.3 客户端连接命令1.2.4 修改Redis配置文件 2. Redis数据类型2.1 五种常用数据类型介绍2.1.1 字符串操作命令2.1.2 哈希操作命令2.1.3 列表操作命令2.1.4 集合操作命令2.1…

代码随想录算法训练营第十天

232.用栈实现队列 方法&#xff1a; 本质 利用两个栈实现 先入先出定义两个栈 一个栈放入数据st_in 一个栈弹出数据st_out注意&#xff1a; 代码&#xff1a; class MyQueue { public:stack<int>st_in; stack<int>st_out;MyQueue() {}void push(int x) {st_…

数学建模【模糊综合评价分析】

一、模糊综合评价分析简介 提到模糊综合评价分析&#xff0c;就先得知道模糊数学。1965年美国控制论学家L.A.Zadeh发表的论文“Fuzzy sets”标志着模糊数学的诞生。 模糊数学又称Fuzzy数学&#xff0c;是研究和处理模糊性现象的一种数学理论和方法。模糊性数学发展的主流是在…

阿珊详解Vue路由的两种模式:hash模式与history模式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

25考研资料PDF汇总

资料V馊public号ZL研知己 V馊public号ZL研知己 25考研资料PDF汇总

ChatGPT/GPT4科研技术应用与AI绘图(包含Claude3、Gemini、Sora、GPTs中大模型的最新技术)

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

第八届世界3D渲染大赛作品在哪看?

精彩纷呈的第八届世界3D渲染大赛作品终于与我们见面了&#xff01;近来&#xff0c;这场赛事吸引了无数3D创意达人的瞩目。作为全球认可度极高、参与者众多的顶级3D动画大赛&#xff0c;今年也不例外&#xff0c;汇集了众多著名的艺术创作者。如果你正在寻找第八届赛事作品的观…

计算阶梯数 Python

题目描述 爱因斯坦曾出过这样一道有趣的数学题&#xff1a; 有一个长阶梯&#xff0c; 若每步上2阶&#xff0c;最后剩1阶&#xff1b; 若每步上3阶&#xff0c;最后剩2阶&#xff1b; 若每步上5阶&#xff0c;最后剩4阶&#xff1b; 若每步上6阶&#xff0c;最后剩5阶&#xf…

Springboot+vue的商业辅助决策系统的设计与实现(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的商业辅助决策系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的商业辅助决策系统的设计与实现&#xff0c;采…

Linux - 进程间通信

1、进程间通信介绍 1.1、进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程&#xff1b;资源共享&#xff1a;多个进程之间共享同样的资源&#xff1b;通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;…

2.5K Star,打造个性化博客平台

2.5K Star&#xff0c;打造个性化博客平台 Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 导语 在当今的信息时代&a…

Python Tkinter GUI 基本概念

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;如果停止&#xff0c;就是低谷&#xf…

AI 应用之路:质疑汤姆猫,成为汤姆猫,超越汤姆猫

过去一年&#xff0c;我对 AI 应用的看法经历了这样一个过程&#xff1a;质疑汤姆猫&#xff0c;理解汤姆猫&#xff0c;成为汤姆猫&#xff0c;超越汤姆猫。 什么是汤姆猫&#xff1f;汤姆猫是 2010 年移动互联网早期的一款应用&#xff0c;迅速走红&#xff0c;又淡出视野。…

【QT】窗口的大小标题图标设置

窗口的大小标题图标设置 添加一个新的类 创建完成&#xff0c;根据上一节最后的在总结&#xff0c;做个测试&#xff1a; #include "mybutton.h" #include <QDebug>//打印&#xff0c;标准输出 MyButton::MyButton(QWidget *parent) : QPushButton(parent) { …