ArkTs面向对象编程

ArkTs面向对象编程

1.1 面向对象编程概述

1.1.1 什么是面向对象编程

面向对象编程是一种编程范式,它使用“对象”来设计软件和创建可重用的程序设计

对象是包含数据和方法的实体,可以与其他对象进行交互

面相对象编程鼓励使用已有的对象来组合或修改以适应新的需求,而不是重新编写代码

打一比方来说,比如我们洗衣服这件事,面向过程就是你需要一步一步的去操作,比如先泡衣服,然后导入洗衣液,然后在一步步的去洗,而面向对象则是,你只需要准备好洗衣液,把衣服分好类,然后放进洗衣机里,到底如何去洗交给洗衣机这个对象,通过调用它的“方法”帮你实现洗衣服这个功能,你并不需要知道内部是如何帮你洗衣服的

1.1.2 面向对象编程的特点

  • 封装
  • 继承
  • 多态

1.1.3 封装

封装:将数据属性和方法封装在一个对象中,形成一个独立的实体,将某些信息隐藏在类内部,通过访问修饰符(public、private、protected)控制成员变量的访问权限,并且封装还可以把相同功能的代码封装到一个类中

  • 提高代码的安全性和可维护性
  • 提高了代码的复用性

我们程序设计追求“高内聚,低耦合

高内聚:类的内部数据操作细节自己完成,不允许外部干涉

低耦合:仅对外部暴露少量的方法用于使用

通俗的说:封装就是把该隐藏的隐藏起来,该暴露的暴露出来,这就是封装的设计思想

1.1.4 案例练习

class Animal{
  //封装动物特征属性
  private name:string;
  private age:number;
  private species:string;

  constructor(name:string,age:number,species:string) {
    this.name=name
    this.age=age
    this.species=species
  }

  //封装动物行为的方法
  public eat():string {
    console.log(`${this.name} is eating`)
    return `${this.name} is eating`
  }
  public getName() {
    return this.name
  }

  public getAge() {
    return this.age
  }

  public getSpecies() {
    return this.species
  }

  public sleep():string {
    console.log(`${this.name} is sleeping`)
    return `${this.name} is sleeping`
  }
}
class Cat extends  Animal{

    hobby:string
    address:string

  constructor(name:string,age:number,species:string,hobby:string,address:string) {
      super(name,age,species)
      this.hobby = hobby
      this.address = address
  }


   swimming() {
      console.log(`${this.getName} is swimming`)
   }

  running() {
     console.log(`${this.getName()} is runing`)
  }

}
let animal1 = new Animal("cat",18,"小橘猫")
console.log(animal1.getName())
console.log(animal1.sleep())

1.1.5 继承

  1. 继承:允许一个子类继承另一个父类的所有属性和方法,同时,使得子类可以复用父类的代码,提高代码的可重复性
  • 继承的特点

    • 使用extends关键字
    • 相当于子类把父类的功能复制了一份
    • ArkTs只支持单继承
    • 继承可以传递(爷爷,儿子,孙子的关系)
    • 不能继承父类的私有成员
    • 继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能扩展
  • 构造方法的使用

    • 子类创建对象时,默认都会去访问父类的无参构造方法
    • 在构造方法的第一行,都有一条默认的雨具:super()
    • 父类没有无参构造时,可以用super调用父类的其他构造:super(参数列表)
  • 继承的要求

    • 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
    • 子类重写的方法返回值类型不能大于父类被重写的方法返回类型
    • 子类重写的方法使用权限不能小于被重写的方法的访问权限
    • 子类方法抛出的异常不能大于父类方法被重写的异常

    注意子类与父类中同名参数的方法必须同时声明为非static得,或者同时声明为static得

  1. 多态:允许使用不同的对象对同一消息做出不同的相应,提高代码的可重用性
  • 多态是指子类可以重写父类的方法,使得在调用时可以根据实际对象类型执行相应的方法

    方法重写:子类提供与父类同名但参数列表不同的方法,称之为方法重写

  • 多态的好处:提高代码的灵活性和可扩展性,方便程序的维护和修改

1.1.6 案例练习

class Animal {
  name:string
  age:number
  species:string
  //构造方法
  constructor(name:string,age:number,species:string) {
    this.name=name;
    this.age=age;
    this.species=species;
  }
  bark() {
    console.log(`它叫${this.name},今年${this.age},它的品种是${this.species},`)
  }
}
class Cat extends Animal{
  hobby:string
  snake:string

  constructor(name:string,age:number,species:string,hobby:string,snake:string) {
    super(name,age,species)
    this.hobby = hobby
    this.snake = snake
  }
}
  let cat1 = new Cat("花花",13,"小橘猫","玩毛球","fish")
  cat1.bark()

1.1.7 面向对象编程的优点

  1. 提高代码可重用性:通过继承和多态,可以重用已有的代码,减少重复工作
  2. 易于维护和扩展:面向对象编程使得代码结构变得更清晰,更容易理解和维护。同时,也更容易扩展功能和添加新特性
  3. 提高软件可扩展性:面相对象编程使得软件更容易扩展和适应新的需求,因为可以通过添加新的类或对象来扩展功能

2.1 类与对象

  1. 类(class):类是对象的抽象描述,它定义了对象的属性(成员变量)和方法(成员函数)

类的声明使用class关键字,类名与变量、函数等命名规则类似,这里要首写字母大写,类名后跟上一对花括号可以理解为类的主体,类的主题三部分组成:成员属性、构造函数、成员方法

class 类名 {
成员属性:在类中可以直接声明变量,也称为成员属性,另外在类中声明成员属性我们还可以使用关键字 private、public、protected来修饰

构造方法:主要用于在创建对象时初始化对象、即对对象的成员变量进行赋值,并在创建对象的语句中与“new"运算符一起用

在类中直接声明函数称为成员方法,注意这里函数时不需要加function关键词,成员方法要和对象有关联,例如eat方法(每个人都需要吃饭的)另外方法也可以使用public、private、protected等关键词声明

}

代码实例

  • 定义了一个Person类,类包含的结构,成员属性:年龄、名字;构造函数constructor();成员方法;公有的etc方法
class Person {
  //成员属性
  name:string
  age:number

  //构造函数进行对成员属性初始化
  constructor(name:string,age:number) {
    this.name=name
    this.age=age
  }
  sayHi():string {
    return `大家好,我叫`+this.name+",我现在"+this.age+"岁了"
  }
}
//对比Java: Person p1 = new Person("小程",20)
let p1=new Person("小程",20)
console.log(p1.name)
console.log(p1.sayHi())

image-20241113094101659

  1. 对象(Object):对象是类的实例,它具有类所定义的属性和方法
  2. 实例化:通过类创建对象的过程称为实例化

2.1.1 如何实例化对象

类对象包含的是类的所有成员对象和类的实例化过程。这些成员对象可以是实例变量、实例方法、类变量和类方法等,它们构成了类对象的主体方法等,它们构成了类对象的主体部分,是类的具体实现。类对象还包含类的属性、关系和实例化过程等,这些内容共同构成了类的完整结构和功能

let 对象名 = new 类名()
let person =new Person()
没有对象,就可以使用new关键字new一个出来

2.1.2 成员访问修饰符

成员属性和成员函数都可以用关键词private、public、protected来修饰

  • public:声明的属性/函数具有公有权限,在类的外部是可以被访问的,public这个关键词默认是可以不用写的
  • private:声明的属性/函数具有私有权限,仅在当前类的内部可以被访问
class Person {
  //成员属性
  name:string
  age:number
   private sex:string

  //构造函数进行对成员属性初始化
  constructor(name:string,age:number,sex:string) {
    this.name=name
    this.age=age
    this.sex='男'
  }
  sayHi():string {
    return `大家好,我叫`+this.name+",我现在"+this.age+"岁了"
  }
  // public getSex():string {
  //   return this.sex
  // }
}
let p1=new Person("小程",20,"")
console.log(p1.name)
console.log(p1.sayHi())

image-20241113100846602

提供一个set方法,把sex属性返回出去

 public getSex():string {
    return this.sex
  }
 console.log(p1.getSex())
  • Protected:protected 成员对于该类及其子类是可见的,但对于该类的实例或外部代码是不可见的。这意味着子类可以访问和修改 protected 成员,但类外部的代码不能。声明的属性/函数具有保护权限,在类的派生内部可以被访问
class MyClass {  
  protected myProperty: string;  
  
  constructor() {  
    this.myProperty = "Hello, protected!";  
  }  
}  
  
class MySubClass extends MyClass {  
  public displayProperty() {  
    console.log(this.myProperty); // 正确:'MySubClass' 可以访问 'MyClass' 中的 'protected' 成员  
  }  
}  
  
const obj = new MyClass();  
console.log(obj.myProperty); // 错误:'myProperty' 是受保护的,不能在类外部访问  
  
const subObj = new MySubClass();  
subObj.displayProperty(); // 正确:'MySubClass' 的方法内部可以访问 'protected' 成员

访问权限的总结

修饰符类内部同一个包不同包的子类同一个工程
private×××
protected××
public

2.1.3 案例练习

案例练习一:创建Person类,有四个属性和方法,分别有一个私有和受保护

class Person {
 private name:string
 protected age:number
  Studentclass:string
  sex:string

  constructor(name:string,age:number,Studentclass:string,sex:string) {
   this.name=name
    this.age=age
    this.Studentclass=Studentclass
    this.sex=sex
  }
  public getName(): string{
   return this.name
}
public getAge():number{
   return this.age
}
 private eating():string{
   return "I am eating snack"
}
  protected drinking():string{
    return "I am drinking juice"
  }

  playing():void{
    console.log("I am playing baseball")
  }
  joying():void{
   console.log("I  am feeled very excited")
  }
  public getPlaying():string{
   return this.eating()
  }
  public getEating():string{
   return this.drinking()
  }


}
let student1=new Person("小张",13,"软件一班","女")
console.log(student1.getName()+"今年"+student1.getAge()+"岁了,我的班级是"+student1.Studentclass+",我的性别是"+student1.sex)
console.log(student1.getEating())
console.log(student1.getEating())
student1.playing()
student1.joying()


image-20241113110408958

案例练习2:创建Person类,有四个属性和方法,分别有一个私有和受保护

class Animal {
   breed:string
 age:number
private name:string
  protected sex:string

  constructor(breed:string,age:number,name:string,sex:string) {
    this.breed=breed
    this.age=age
    this.name=name
    this.sex=sex
  }
  public getName(): string{
    return this.name
  }
  public getSex():string{
    return this.sex
  }
  private swimming():string{
    return "I am eating snack"
  }
  protected walking():string{
    return "I am drinking juice"
  }

  running():void{
    console.log("I am running")
  }
  jumping():void{
    console.log("I  am jumping")
  }
  public Getswimming():string{
    return this.swimming()
  }
  public Getwalking():string{
    return this.walking()
  }


}
let Cat= new Animal("小橘猫",3,"球球","母")
let Cat= new Animal("小橘猫",3,"球球","母")
console.log(Cat.getName()+"今年"+Cat.age+"岁了,我的品种是"+Cat.breed+",我的性别是"+Cat.getSex())
console.log(Cat.Getswimming())
console.log(Cat.Getwalking())
Cat.running()
Cat.jumping()

image-20241113110621623

3.1 接口与抽象

3.1.2 接口概念

接口的作用:在面向对象的编程中,接口是种规范的定义, 它定义了行为和动作的规范, 在程序设计里面,接口起 到一种限制和规范的作用。接口定义了某-批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方,提供这些方法的类就可以满足实际需要。
ArkTs接口(interface)定义是一种在HarmonyOs系统中用于定义对象之间交互规则的方式。通过使用ArkTS接口,开发者可以明确的规范一个类必须实现的方法和属性,从而确保代码的健壮性和可维护性

3.1.2 ArkTs接口定义的核心概念

方法定义:在ArkTs接口中,你可以定义一个或多个方法的签名,包括方法名、参数列表和返回类型

interface MyInterface {
	myMethod(Parameter:number):void
}

属性定义:除了方法之外,ArkTs接口中还可以定义属性

interface MyInterface {
	myProperty:number;
}

实现接口:一旦你定义了一个接口,你可以让类来实现该接口,一个类实现一个接口意味着该必须提供接口中定义的所有方法的具体实现

class MyClass implements MyInterface {
	myMethod(param:number) {
	console.log(`Called myMethid with param ${param}`);
	}
}

3.1.3 ArkTS接口操作

  • 定义接口interface,实现接口用implements,以下是定义接口和实现接口的用例

  • 定义Style接口,包含接口属性,方法

interface Style {
colorValue:string  //属性
color(x:stirng)  //方法
}
  • 定义StyledRectangle类,实现Style接口方法
class StyledRectangle implements Style {
	private colorValue:string = ""
	color(x:string)
	this.color = x
}

案例练习

interface StyleC {
  colorValue:string
  color(c:string):void//方法
}
interface ExtendedStyle extends StyleC {
  setWidth(x:number):void //设置宽度
  //获取宽度
  getWidth():string

  }
 
//接口实现
class TestStyle implements ExtendedStyle{
      colorValue: string
      mWidth:number

  constructor(colorValue:string,_Width:number) {
        this.colorValue=colorValue;
        this.mWidth=_Width

    }
  color(c:string):void {
    // this.colorValue = c
    console.log("嘻嘻嘻嘻嘻")
  }
   setWidth(x: number): void {
        // this.mWidth = x
     console.log("哈哈哈哈哈")
   }

    getWidth():string{
          return '宽度为'+this.mWidth+",颜色为"+this.colorValue
    }



}
//创建实例化对象
let Style = new TestStyle('blue',500)
console.log(Style.getWidth())

image-20241113165858061

3.1.4 ArkTs抽象类概述

我们知道,类用来模拟现实事物。一个类可以模拟一类事物,而某个类的一个实例化对象可以模拟某个属于该类的具体的事物。类中描绘了该类所有对象共同的特性,当一个类中给出的信息足够全面时,我们就可以实例化该类;比方说,在Dog类中定义了name,age,等属性,以及play,eat等行为时,我们就可以创建一个Dog类对象,来模拟某个具体的Dog,比如你家的宠物狗,或者是神犬小七等。但是,当一个类中给出的信息不够全面时,(比方说有无法确定的行为),它给出的信息不足以描绘出一个具体的对象,这时我们往往不会实例化该类,这种类就是抽象类。打个比方,对于Animal类,是,所有的动物都有吃喝的行为,定义eat方法可以描述某一种动物“吃”这一行为,但是每种动物吃的都不一样,因此一个eat方法并不能准确描述吃什么,怎么吃。这时Animal给出的信息就不足够描述一个对象,我们就不能去实例化Animal类。如下面代码演示

  1. 首先定义一个抽象类
abstract class Animal {
  abstract makeSound():void
  abstract  move():void

  baseInfo() :void{
    console.log("我是一只动物")
  }
}
  1. 实现这个抽象类(可以是任意动物)
class Dog extends Animal{
  makeSound(): void {
    console.log("小狗在汪汪叫");
  }
  move(): void {
    console.log("小狗再跑");
  }
}

class Cat extends Animal{
  makeSound(): void {
    console.log("小猫在汪汪叫");
  }
  move(): void {
    console.log("小猫再跑");
  }
}

3.1.5 多态的定义

多态是什么?

  • 多态是同一个行为具有不同的表现形式或形态的能力
  • 同一方法可以根据发送对象的不同而采用不同的行为方式

比如:打印机分为黑白打印机和彩色打印机,在黑白打印机情况下打出来为黑白,在彩色打印机的情况下打印出来为彩色

image-20241114204231462

多态就是事务的多种形态,一个对象在不同条件下所表现的形式

3.1.6 多态的存在条件

多态存在的三个必要条件

  1. 继承或实现:在多态中必须存在有继承或实现关系的子类和父类
  2. 方法的重写:子类对父类中的某些方法进行重新定义
  3. 基类引用指向派生类对象,即父类引用子类对象
  • 方法的重写

重写(override):也称覆盖。重写是子类对父类非静态、非private修饰,非构造方法等的实现过程进行重新编写,返回值和形参都不能改变。重写的目的也就是根据自己的需要,定义特定于自己的行为

  • 重写的条件

    • 参数列表相同
    • 方法名相同
    • 返回类型相同
  • 重写和重载的区别

    区别重写重载
    参数列表一定不能被修改必须修改
    返回类型一定不能修改除非可以构成父子关系可以修改
    访问修饰符一定不能修改更严格的限制可以修改

3.1.7 案例练习

  1. 类实现多态

子类可以继承父类的属性和方法,并且可以重写父类的方法

//类实现多态
class Animal {
  name:string;

  constructor(name:string) {
    this.name=name;
  }

  speak():string{
    console.log(`${this.name} is speaking`);
    return `${this.name} is speaking`
  }
}
class Dog extends Animal {
  //重写父类的方法
  speak(): string {
    console.log(`${this.name} is barks and wags its tail`)
    return`${this.name} barks and wags its tail`
  }
}

let dog = new Dog("花花")
dog.speak()
class Person {
  name:string

  constructor(name:string) {
    this.name = name
  }

  speak() {
    console.log(`${this.name}在发言`)
  }

}
let person1 = new Person("小红")
class  Student extends Person{

  speak(): string {
    console.log(`${this.name}使用英语对自己进行发言`)
    return `${this.name}使用英语对自己进行发言`
  }

}

class App{
  message:string

  constructor() {
    this.message=""//没有传值
  }

  aboutToAppear() {
    //创建实例化对象,并调用实例对象的方法
    let s1 = new Student("小张")
    this.message = s1.speak()

  }


}
let app1 =new App()
app1.aboutToAppear()
console.log(app1.message)
  1. 接口实现多态
interface ISspeakable {
  speak():string;//不提供方法

}

class Animal implements ISspeakable {
  name:string;

  constructor(name:string) {
    this.name=name
  }
  speak(): string {
    console.log(`${this.name} makes a noise`)
    return `${this.name} make a noise`
  }
}
let animal = new Animal("花花")
animal.speak()
interface ISpeakable {
  speak(): string;//定义了有speak方法
}

//定义了一个动物类,实现了ISpeakable
class Animal implements ISpeakable {
  name: string;
  message: string

  constructor(name: string, message: string) {

    this.name = name
    this.message = message
  }

  speak(): string {

    console.log(`${this.name} make noise`)
    return `${this.name} make noise.\n`

  }




}

class App {
  message:string

  constructor() {
    this.message=""
  }

  aboutToAppear() {
    const animal = new Animal("小猫咪","喵喵喵")
    this.message = animal.speak()
  }
}
let app =new App()
app.aboutToAppear()
console.log(app.message)

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

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

相关文章

乳腺癌诊断分析——基于聚类分析实现

一、研究背景 乳腺癌属于恶性肿瘤,在早期发现后需要及早将病变组织切除,而且术后还要化疗和放射等辅助治疗,能够抑制癌细胞的扩散和增长。 二、研究目的 研究乳腺癌病人的患病特征通过聚类分析方法对特征进行分类通过上述聚类结果对乳腺诊…

丹摩征文活动|FLUX.1 和 ComfyUI:从部署到上手,轻松驾驭!

FLUX.1 和 ComfyUI:从部署到上手,轻松驾驭! FLUX.1历史曲线 黑森林实验室推出了一款名为FLUX.1的先进图像生成模型,根据不同用户需求,提供了三种独特的版本。 FLUX.1-pro:作为专为企业打造的强大闭源版本…

数据分析:16s差异分析DESeq2 | Corncob | MaAsLin2 | ALDEx2

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍DESeq2原理计算步骤结果Corncob原理计算步骤结果MaAsLin2原理计算步骤结果ALDEx2原理计算步骤结果加载R包数据链接数据预处理微生物数据样本信息提取物种名称过滤零值保留结果读取…

OCR识别铁路电子客票

随着中国铁路客运领域进入全面数字化时代,国家税务总局、财政部和国铁集团于2024年10月18日联合发布公告,自2024年11月1日起,推广使用“电子发票(铁路电子客票)”。这一举措不仅为旅客出行提供了极大的便利&#xff0c…

【MySQL基础刷题】总结题型(三)

十题左右,便于复习 1.查询结果的质量和占比2.每月交易I3.销售分析III4.只出现一次的最大数字5.买下所有产品的客户6.员工的直属部门7.指定日期的产品价格 1.查询结果的质量和占比 avg大神啊… SELECT query_name, ROUND(avg(rating / position), 2) as quality, …

python 同时控制多部手机

在这个智能时代,我们的手机早已成为生活和工作中不可或缺的工具。无论是管理多个社交媒体账号,还是处理多台设备上的事务,如何更高效地控制多个手机成为了每个人的痛点。 今天带来的这个的软件为你提供了一键控制多部手机的强大功能。无论是办公、娱乐,还是社交,你都能通过…

外星人入侵

学习于Python编程从入门到实践(Eric Matthes 著) 整体目录:外星人入侵文件夹是打包后的不必在意 图片和音效都是网上下载的 音效下载网站:Free 游戏爆击中 Sound Effects Download - Pixabay 运行效果:可以上下左右移…

前端监控与埋点 全总结

一、概念 前端埋点是指在网页或者应用程序中插入特定的代码,用于收集用户的行为数据并发送给服务器进行分析。这些数据可以包括用户的点击、浏览、输入等操作,帮助开发者了解用户的在其网站中的行为,从而进行针对性的优化和改进。 前端埋点…

Python简单文件操作day9

1、文件操作的重要性和场景 重要性: 数据持久化、跨平台兼容性、数据备份与恢复、数据共享、配置管理、日志记录 应用场景: 数据分析、web开发、文本处理 2、文件的概念 文件是一个存储在某种持久性存储介质【硬盘、光盘、磁盘等】上的数据的结合。 …

指令存储和指令流水线

要求存储器的编址单位,首先观察到计算机采用的是32位定长指令字,因此一条指令就是32位,即4B,根据表中可知一条指令所占地址空间为08048104H-08048100H4H,因此所用的编制单位为字节(B) 将所有指令…

kafka管理工具

文章目录 前言一、Kafka Assistan1.1 描述1.2、配置安装 二、Conduktor2.1、描述2.2、配置安装 三、kafka-maneger3.1、描述3.2、配置安装3.3、命令启动3.4、[refer to](https://www.ctyun.cn/document/10000120/10033218#section-39755766f4910e4b) 前言 提示:这里…

JavaWeb常见注解

1.Controller 在 JavaWeb 开发中,Controller是 Spring 框架中的一个注解,主要用于定义控制器类(Controller),是 Spring MVC 模式的核心组件之一。它表示该类是一个 Spring MVC 控制器,用来处理 HTTP 请求并…

axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)

fetch 是啥? fetch 函数是 JavaScript 中用于发送网络请求的内置 API,可以替代传统的 XMLHttpRequest。它可以发送 HTTP 请求(如 GET、POST 等),并返回一个 Promise,从而简化异步操作 基本用法 /* 下面是…

window任务计划记录中显示操作成功,但是代码只执行了第一句命令

一、创建定时任务 1. Windows键R 调出此窗口,输入compmgmt.msc (调用的是计算机管理) 2. 创建基本任务 在任务计划程序中右键 选择 创建基本任务。 输入任务名称及描述。 下一步中选择触发器的时间,这里选择每天。 选择开始时间&…

使用VSCode远程连接服务器并解决Neo4j无法登陆问题

摘要:本文介绍了如何通过VSCode连接内网部署的Neo4j服务器,并启动服务。在访问Neo4j登录界面时,遇到了端口映射问题导致无法登录。通过手动添加7687端口的映射后,成功登录Neo4j。 我在内网部署了一台服务器,并在其上运…

【异常解决】Linux shell报错:-bash: [: ==: 期待一元表达式 解决方法

博主介绍:✌全网粉丝21W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

游戏引擎学习第四天

视频参考:https://www.bilibili.com/video/BV1aDmqYnEnc/ BitBlt 是 Windows GDI(图形设备接口)中的一个函数,用于在设备上下文(device context, DC)之间复制位图数据。BitBlt 的主要用途是将一个图像区域从一个地方复…

七牛云上传图片成功,但是无法访问显示{error : document not found}

上传图片成功,但是访问不了的问题,直接把地址放进浏览器显示{error : document not found},直接访问 DCNF 404是符合预期的,因为还没有去空间复制外链,要访问实际存在的资源才可以的. 配置区域和访问域名 设置没问题了…

通过投毒Bingbot索引挖掘必应中的存储型XSS

简介 在本文中,我将讨论如何通过从外部网站对Bingbot进行投毒,来在Bing.com上实现持久性XSS攻击。 什么是存储型或持久性XSS?存储型攻击指的是将恶意脚本永久存储在目标服务器上,例如数据库、论坛、访问日志、评论栏等。受害者在…

84.7k Star!Excalidraw:开源的在线白板工具,具备手绘风格和实时协作功能

❤️ 如果你也关注大模型与 AI 的发展现状,且对大模型应用开发非常感兴趣,我会快速跟你分享最新的感兴趣的 AI 应用和热点信息,也会不定期分享自己的想法和开源实例,欢迎关注我哦! 🥦 微信公众号&#xff…