C#学习笔记 - C#基础知识 - C#从入门到放弃 - C# 接口、抽象与密封

C# 入门基础知识 - C# 接口、抽象与密封

  • 第10节 接口、抽象与密封
    • 10.1 接口的声明
    • 10.2 接口的实现和继承
    • 10.3 显式实现接口
    • 10.4 抽象类与抽象方法声明
    • 10.5 抽象方法(abstract)方法与虚方法(virtual)方法
    • 10.6 密封类与密封方法
    • 10.7 接口综合运用实践

更多C#基础知识点可查看:C#学习笔记 - C#基础知识 - C#从入门到放弃

第10节 接口、抽象与密封

10.1 接口的声明

在C#中,接口(interfaces)是一种定义了一组合同类型的成员(方法、属性、索引器和事件)的契约。接口定义了一种抽象的行为规范,而不关注具体的实现细节。类可以实现(implement)一个或多个接口,实现接口的类需要提供接口中定义的全部成员的具体实现。

接口的作用主要有以下几点:
规范行为:接口定义了一组行为规范,类通过实现接口来遵循规范。这有助于提高代码的一致性和可读性。
多态性:通过接口,可以通过接口类型的引用来引用实现了接口的类的对象。这使得我们可以编写更灵活的代码,并实现多态性。
支持多重继承:C#中不支持类的多重继承,但是一个类可以实现多个接口。这使得我们可以通过多个接口来组合不同的行为,并避免了单继承的限制。
接口隔离原则:接口提供了一种将抽象与实现分离的方式,符合面向对象设计的接口隔离原则。接口使得类与类之间的耦合度降低,提高了代码的可维护性和可扩展性。

1、接口声明
语法:

修饰符 interface 接口名称	//接口名称一般以I开头able结尾
{
成员;
}
    interface IEatable		//接口名称一般以I开头able结尾{//接口默认声明为public   类的的默认声明是private//接口中不能有访问修饰符//由于接口中不能有字段,所以属性经常被写作为自动属性//private string _name;//属性string Name{get;set;}//方法  方法不能包含方法体void food();}

2、【代码示例】

interface IResizable
{void Resize(int width, int height);double Scale { get; set; }
}class Rectangle : IResizable
{public void Resize(int width, int height){// 实现具体的尺寸调整逻辑}public double Scale{get { return 1.0; }set { /* 实现具体的比例调整逻辑 */ }}
}

在上述代码示例中,定义了一个名为 IResizable 的接口,它包含了两个成员:一个方法Resize和一个属性Scale。方法Resize没有具体的实现,只有方法签名,即方法名和参数列表。属性Scale包含了一个get和一个set访问器。Rectangle类使用implements关键字实现了IResizable接口,并提供了接口中定义的Resize方法和Scale属性的具体实现。

10.2 接口的实现和继承

接口继承规则:
实现过程必须在实现接口的类中完成;
类继承具有单根性,接口可多重继承;
父接口也成为该接口的显示基接口;
接口多重继承时,派生接口名与父接口名用冒号隔开,多个父接口之间用逗号隔开;
接口成员之间不能同名;继承的成员不用在声明。

【示例代码】
老鹰(eagle)、麻雀(sparrow)、鸵鸟(ostrich)都是鸟类(birds),根据三者的共性提取出鸟类作为父类,但是它们都有各自特点:
老鹰吃小鸡,麻雀吃粮食,驼鸟吃青草;
老鹰和麻雀都会飞,但是鸵鸟不会;
新增一个天鹅(swan),天鹅吃鱼也会飞;
再新增一个气球(balloon),它会飞但是不是鸟类( 只能继承接口)
1、Bird

    abstract class Bird{public abstract void Eat();}

2、接口IFlyable

   interface IFlyable{void Fly();}

3、

    //定义Ealge类,继承Bird类和IFlyable接口class Eagle:Bird,IFlyable{public override void Eat(){Console.WriteLine("这是老鹰,老鹰吃小鸡。");}//接口的实现过程需要在实现接口的类中进行实现public void Fly(){Console.WriteLine("这是老鹰,老鹰会飞。");}}//定义Sparrow 类,继承Bird类和IFlyable接口class Sparrow : Bird,IFlyable{public override void Eat(){Console.WriteLine("这是麻雀,麻雀吃粮食。");}public void Fly(){Console.WriteLine("这是麻雀,麻雀会飞。");}}//定义Ostrich 类,继承Bird类class Ostrich : Bird{public override void Eat(){Console.WriteLine("这是鸵鸟,鸵鸟吃青菜。");}}//定义Swan类,继承Bird类和IFlyable接口class Swan:Bird,IFlyable{public override void Eat(){Console.WriteLine("这是天鹅,天鹅吃鱼。");}public void Fly(){Console.WriteLine("这是天鹅,天鹅会飞。");}}//定义Balloon类,继承IFlyable接口class Balloon:IFlyable{public void Fly(){Console.WriteLine("这是气球,气球会飞。");}}

4、主体代码

    class Program{static void Main(string[] args){//老鹰(eagle)、麻雀(sparrow)、鸵鸟(ostrich)都是鸟类(birds)//根据三者的共性提取出鸟类作为父类//但是它们都有各自特点:老鹰吃小鸡,麻雀吃粮食,驼鸟吃青草。//老鹰和麻雀都会飞,但是鸵鸟只会奔跑//新增一个天鹅(swan),天鹅吃鱼也会飞//再新增一个气球(balloon),它会飞但是不是鸟类 - 只能继承接口Bird[] birds = { new Eagle(), new Sparrow(), new Ostrich(), new Swan() };foreach (Bird outbird in birds)outbird.Eat();IFlyable[] flys = { new Sparrow(), new Eagle(),new Swan(),new Balloon() };foreach (IFlyable outfly in flys)outfly.Fly();Console.ReadKey();}}

运行程序:

这是老鹰,老鹰吃小鸡。
这是麻雀,麻雀吃粮食。
这是鸵鸟,鸵鸟吃青菜。
这是天鹅,天鹅吃鱼。
这是麻雀,麻雀会飞。
这是老鹰,老鹰会飞。
这是天鹅,天鹅会飞。
这是气球,气球会飞。

10.3 显式实现接口

隐式地实现接口:
既可用接口调用方法,也可以用具体的类调用方法。

显示的实现接口,实现接口的方法前不能用访问修饰符public,必须显示指定接口名称:

void 接口名称.方法()
{//方法体
}

显式实现接口作用:指定方法是哪个接口中的
显式实现接口调用:无法通过具体类来调用,只能通过接口调用

【代码示例】
1、父类 - Bird

    abstract class Bird{public abstract void Eat();}

2、接口 - IFlyable1、IFlyable2

    interface IFlyable1{void Fly();}interface IFlyable2{void Fly();}

3、Eagle类 - 继承Bird类和IFlyable1接口

    class Eagle:Bird,IFlyable1{public override void Eat(){Console.WriteLine("这是老鹰,老鹰吃小鸡。");}public void Fly(){Console.WriteLine("(隐式显示)这是老鹰,老鹰会飞。");}}

调用:

    class Program{static void Main(string[] args){//接口实例化//隐式地实现接口//接口调用IFlyable1 eagle1 = new Eagle();eagle1.Fly();//具体类调用Eagle eagle2 = new Eagle();eagle2.Eat();eagle2.Fly();Console.ReadKey();}}

运行程序:

(隐式显示)这是老鹰,老鹰会飞。
这是老鹰,老鹰吃小鸡。
(隐式显示)这是老鹰,老鹰会飞。

运行结果可知:
当类中是隐式接口时,不论采用接口调用或具体类调用结果都是隐式显示。

4、Balloon类 - 同时继承IFlyable1和IFlyable2接口

    class Balloon:IFlyable1,IFlyable2{//显式实现接口void IFlyable1.Fly(){Console.WriteLine("这是继承的IFlyable1中的Fly()方法。");}void IFlyable2.Fly(){Console.WriteLine("这是继承的IFlyable2中的Fly()方法。");}}

调用:

    class Program{static void Main(string[] args){//接口实例化//显式地实现接口 - 指定方法是哪个接口中的//接口调用IFlyable1 balloon1 = new Balloon();balloon1.Fly();IFlyable2 balloon2 = new Balloon();balloon2.Fly();//具体类调用 - 无法通过具体类来调用,只能通过接口调用//Balloon balloon3 = new Balloon();//balloon3.Fly();Console.ReadKey();}}

运行程序:

这是继承的IFlyable1中的Fly()方法。
这是继承的IFlyable2中的Fly()方法。

继承多个具有相同方法时候,需采用显示实现接口,显式实现接口目的是指定方法是哪个接口中的,其调用时无法通过具体类来调用,只能通过接口调用。

5、Sparrow类 - 继承Bird类和IFlyable1(隐式实现、显示实现同时存在)

    class Sparrow:Bird,IFlyable1{public override void Eat(){Console.WriteLine("这是ma麻雀,麻雀吃粮食。");}public void Fly(){Console.WriteLine("(隐式实现)这是麻雀,麻雀会飞。");}void IFlyable1.Fly(){Console.WriteLine("(显式实现)这是麻雀,麻雀会飞。");}}

调用:

    class Program{static void Main(string[] args){//同时显示和隐式实现接口方法 - 类中同时存在隐式接口和显示接口IFlyable1 sparrow1 = new Sparrow();sparrow1.Fly();     //显示实现 - (隐式实现)这是麻雀,麻雀会飞。Sparrow sparrow2 = new Sparrow();sparrow2.Fly();     //隐式实现 - (显式实现)这是麻雀,麻雀会飞。Console.ReadKey();}}

运行程序:

(显式实现)这是麻雀,麻雀会飞。
(隐式实现)这是麻雀,麻雀会飞。

由结果可知:
当类中同时存在隐式接口和显示接口时,用接口调用是显示实现,用具体类调用是隐式实现。
注意与类中只有隐式接口的区别:
类中只有隐式接口时,不论采用接口调用或具体类调用结果都是隐式显示。

10.4 抽象类与抽象方法声明

在C#中,抽象类和抽象方法是面向对象编程中的重要概念。它们用于定义和组织具有共同特征和行为的类和方法。下面分别介绍抽象类和抽象方法的声明。

1、抽象类(Abstract Class):
抽象类是一种不能被实例化的类,只能被继承。抽象类用于作为其他类的基类,提供一种通用的模板或契约,并定义了一些抽象方法和/或具体方法。抽象类通过将其成员声明为抽象方法或具体方法来定义其行为。
抽象类的声明格式如下:

abstract class ClassName
{// 抽象方法和具体方法的声明
}

抽象类可以包含以下成员:
① 抽象方法(Abstract Method):抽象方法是一种没有实现体的方法,只包含方法签名。它没有具体的实现代码,需要在派生类中进行实现。
② 具体方法(Concrete Method):具体方法是在抽象类中有具体实现的方法。它提供了类的通用行为,可以被派生类直接使用。
使用抽象类的主要目的是为了实现继承和多态性的概念,将一组相关的类进行抽象和归类,从而提高代码的可维护性和可扩展性。

2、抽象方法(Abstract Method):
抽象方法是一种没有实现体的方法,只包含方法签名。抽象方法必须定义在抽象类中,用于在派生类中进行具体实现。

抽象方法的声明格式如下:

abstract returnType MethodName(parameters);

抽象方法只包含方法的声明部分,没有具体的实现代码。它用于定义一个方法的特征和接口,而不涉及具体的实现细节。抽象方法必须使用abstract关键字进行声明,并且必须在抽象类中进行定义。

派生类必须实现父类中的抽象方法,并提供具体的实现代码。如果派生类没有实现抽象方法,那么派生类也必须声明为抽象类。

需要注意:
① 抽象类使用abstract关键字进行声明,并且不能被实例化。
② 抽象方法使用abstract关键字进行声明,并且没有方法体。
③ 抽象方法必须在抽象类中声明,在派生类中必须实现(重写)抽象方法。
④ 抽象类可以包含普通成员(属性、方法等),不限制具体实现。

【代码示例】

    //声明抽象类  必须包含abstract关键字//抽象类的声明就是为了实现派生或者继承,因此不可将其私有化public abstract class Class1{//声明抽象方法  必须包含abstract关键字  且不能有方法体public abstract void Method1();public abstract void Method2();//抽象类中课可以包含非抽象方法public void Add(int a,int b){Console.WriteLine(a+b);}}//如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类public abstract class Class2 : Class1{public override void Method1(){Console.WriteLine("这是Class2继承Class1中的Method1。");}}

抽象类非抽象类
抽象类前有关键字 abstract,抽象方法不提供任何实际实现;没有则为非抽象类

注意:
抽象方法必须在抽象类中声明;
不能使用staticprivatevirtual修饰符;
方法不能有任何可执行程序,方法体也不行
重写抽象方法时采用override抽象类不能实例化,必须通过继承由派生实现其抽象方法,因此不能new,不能sealed
如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。
如果一个非抽象类从抽象类中派生,则其必须通过重载来实现所有继承而来的抽象成员。

10.5 抽象方法(abstract)方法与虚方法(virtual)方法

在C#中,抽象方法(abstract method)和虚方法(virtual method)都是用于实现多态性的机制,但它们在用法和行为上有一些异同点。

相同点:
① 都用于实现多态性:抽象方法和虚方法都是面向对象编程中的多态性的实现方式。它们允许派生类在继承基类的同时,对方法进行不同的实现,实现方法的重写。
② 都只存在于父类中:抽象方法和虚方法都属于父类中的成员,子类可以重写这些方法,但不可以直接调用父类的实现。
③ 都可以通过override来实现对原有方法的重写。

不同点:
① 实现方式不同:抽象方法必须声明在抽象类中,没有具体的实现,需要在派生类中进行实现。而虚方法是在父类中有具体的实现,并使用virtual关键字进行声明,可以选择性地在派生类中进行重写。
② 强制实现 vs 可选实现:抽象方法强制派生类对其进行实现,如果派生类没有实现抽象方法,那么派生类本身也必须声明为抽象类。而虚方法在派生类中实现是可选的,派生类可以选择是否重写虚方法。
③ 调用方法不同:抽象方法只能通过派生类对象的实例进行调用,因为抽象类不能被实例化。而虚方法可以通过父类对象的实例和派生类对象的实例进行调用。

【程序示例】 通过抽象方法与虚方法实现计算x的y次幂的值。
抽象方法:

    abstract class Pow{public abstract void PowMethod(int x, int y);}class PowB : Pow{public override void PowMethod(int x, int y){int pow = 1;for(int i = 1; i <= y; i++){pow *= x;}Console.Write("abstract方法类中PowB派生类继承Pow方法,自定义计算幂:");Console.WriteLine("{0}的{1}次幂是{2}",x,y,pow);}      }class PowC : Pow{public override void PowMethod(int x, int y){Console.Write("abstract方法类中PowC派生类继承Pow方法,系统函数计算:");Console.WriteLine("{0}的{1}次幂是{2}", x, y, System.Math.Pow(x, y));}}class Program{static void Main(string[] args){PowB pow1 = new PowB();pow1.PowMethod(2, 3);PowC pow2 = new PowC();pow2.PowMethod(2, 3);Console.ReadKey();}}

运行程序:

abstract方法类中PowB派生类继承Pow方法,自定义计算幂:23次幂是8
abstract方法类中PowC派生类继承Pow方法,系统函数计算:23次幂是8

虚方法:

    class Pow{public virtual void PowMethod(int x, int y){int pow = 1;for (int i = 1; i <= y; i++){pow *= x;}Console.Write("virtual方法类中Pow 基类定义的Pow方法,自定义计算幂:");Console.WriteLine("{0}的{1}次幂是{2}", x, y, pow);}}class PowB:Pow{public override void PowMethod(int x, int y){Console.Write("virtual方法类中PowB派生类继承Pow方法,系统函数计算:");Console.WriteLine("{0}的{1}次幂是{2}", x, y, System.Math.Pow(x, y));}}class Program{static void Main(string[] args){Pow pow1 = new Pow();pow1.PowMethod(2, 3);PowB pow2 = new PowB();pow2.PowMethod(2, 3);Console.ReadKey();}}

运行程序:

virtual方法类中Pow 基类定义的Pow方法,自定义计算幂:23次幂是8
virtual方法类中PowB派生类继承Pow方法,系统函数计算:23次幂是8

10.6 密封类与密封方法

在C#中,密封类(sealed class)和密封方法(sealed method)用于限制继承和重写的行为。它们可以被用来避免进一步派生和重写,提供更严格的类和方法的定义。

1、密封类(Sealed Class):
密封类是一种用于限制继承的特殊类。当一个类被声明为密封类时,它不能被其他类继承。密封类用于表示某个类的最终实现,禁止通过派生创建新的子类。

密封类的声明格式如下:

sealed class ClassName
{// 类的定义
}

要注意以下几点:

① 密封类必须是最终类,可以继承其他类,但不能被其他类继承;不能作为基类供其他类进行派生。
② 密封类可以包含字段、属性、方法、事件等成员,具体根据需求定义即可;可以包含成员和方法,可以具有抽象成员、虚成员或普通成员。
③ 密封类与抽象类是相反的概念,抽象类用于表示可以被继承的类,而密封类用于表示不能被继承的类。
④ 使用密封类的主要目的是为了避免类被进一步继承,强制类作为最终实现,从而确保类的完整性和稳定性。例如,System.String类就是一个密封类,它不能被继承。

2、密封方法(Sealed Method):
密封方法是一种用于限制重写的方法。当一个方法被声明为密封方法时,它不能被派生类进一步重写。密封方法用于表示某个方法的最终实现,禁止在派生类中重新定义该方法。

密封方法的声明格式如下:

class ClassName
{sealed returnType MethodName(parameters){// 方法体}
}

要注意以下几点:
① 密封方法必须是已重写的方法,并在声明时使用sealed关键字进行标记。
② 密封方法只能在派生类中重写一次,而派生类中的任何子类都无法重写密封方法。
③ 密封方法不能在非虚方法或非重写方法中在C#中,密封类(sealed class)和密封方法(sealed method)是用于限制类和方法的继承和重写的关键字。
④ 使用密封方法的主要目的是为了禁止在派生类中进一步重写某个方法,确保方法的逻辑完整性和稳定性。

【密封类的示例】

sealed class MySealedClass
{public void SomeMethod(){Console.WriteLine("This is a method in a sealed class.");}
}

说明:
MySealedClass是一个密封类,它声明了一个方法SomeMethod( )。这个类不能被其他类继承,因此不能有子类。

【密封方法的示例】

class MyBaseClass
{public virtual void SomeMethod(){Console.WriteLine("This is the base method.");}
}class MyDerivedClass : MyBaseClass
{sealed override void SomeMethod(){Console.WriteLine("This is a sealed method in a derived class.");}
}

10.7 接口综合运用实践

多态的实现方法:
①虚方法: 可以抽象出一个类,并且这个类需要有实现
②抽象类: 可以抽象出一个父类,但是抽象类需要有一个方法且实现方法的途径不确定,不需要父类创建对象
③接口: 不能抽象出一个父类,但是可以找他们的共同点,也就是共同行为、能力即共同的属性和方法,接口的表明是一种能力,一种规范

【实例】 真猫不会说话,Tom猫会说话,Kitty猫会说话。
分析:
① 如果采用虚方法定义一个 的基类,需要定义说话的方法,但是真猫不能说话 所以无法派生继承
② 需要定义一个父类定义说话的方法,抽象不能父类中定义方法,所以不乏实现
③ "会"与“不会”说话是一种能力,可以采用接口实现
程序代码:

    //定义接口interface ISaywords{void Say();}//定义RealCat、TomCat和KittyCat类class RealCat{public void Say(){Console.WriteLine("我是真猫子,我不会说话,喵喵喵。");}}class TomCat:ISaywords{public void Say(){Console.WriteLine("我是Tom猫,我会说话,TomTom。");}}class KittyCat:ISaywords{public void Say(){Console.WriteLine("我是Kitty猫,我会说话,KittyKitty。");}}class Program{static void Main(string[] args){RealCat cat = new RealCat();cat.Say();ISaywords[] cats = { new TomCat(),new KittyCat()};foreach (ISaywords outcat in cats)outcat.Say();Console.ReadKey();}}

运行程序:

我是真猫子,我不会说话,喵喵喵。
我是Tom猫,我会说话,TomTom。
我是Kitty猫,我会说话,KittyKitty。

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

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

相关文章

ueditor富文本编辑器中图片上传地址配置以及抓取远程图片地址的配置

一&#xff1a;图片上传保存地址配置 打开文件ueditor.php,找到imagePathFormat进行修改即可 一&#xff1a;远程抓取图片配置 打开文件ueditor.config.js,找到catchRemoteImageEnable&#xff0c;取消注释即可

2024年元旦节放假通知

致尊敬的客户以及全体同仁&#xff1a; 旧岁已展千重锦&#xff0c;新年再进百尺竿。在这辞旧迎新之际&#xff0c;易天光通信提前祝您元旦快乐&#xff01;生意兴隆&#xff0c;身体健康&#xff0c;万事如意&#xff01;根据国家法定假期的规定&#xff0c;并结合公司实际情…

使用pycharm虚拟环境和使用conda管理虚拟环境的区别

使用 PyCharm 虚拟环境和使用 Conda 管理虚拟环境有一些区别&#xff0c;主要涉及到环境的创建、依赖管理、跨平台性等方面。以下是一些关键区别&#xff1a; 创建环境&#xff1a; PyCharm 虚拟环境&#xff1a; PyCharm 使用其自己的虚拟环境管理器&#xff08;通常是 venv&a…

开源verilog模拟 iverilog verilator +gtkwave仿真及一点区别

开源的 iverilog verilator 和商业软件动不动几G几十G相比&#xff0c;体积小的几乎可以忽略不计。 两个都比较好用&#xff0c;各有优势。 iverilog兼容性好。 verilator速度快。 配上gtkwave 看波形&#xff0c;仿真工具基本就齐了。 说下基本用法 计数器 counter.v module…

【接口测试】Postman(一)--接口测试知识准备 _

1.0 前言 ​ 应用程序编程接口&#xff08;Application Programming Interface, API&#xff09;是这些年来最流行的技术之一&#xff0c;强大的Web应用程序和领先的移动应用程序都离不开后端强大的API。API技术的应用给系统开发带来了便利&#xff0c;但也对测试人员提出了更高…

Redis主从切换(单点故障)解决源码

1、使用过程&#xff1a; 发布创建channel1消息 redis-cli> PUBLISH channel1 "Hello, world!" redis-cli> SUBSCRIBE channel1 优点&#xff1a; 1、采用Reactor事件单线程去驱动发布订阅事件的&#xff0c;实时性高。 2、从redis架构去思考&#xff0c;拓展哨…

4.vue学习笔记(事件处理+事件参数+事件修饰符)

文章目录 1.事件处理1.1.内联事件处理器 2.事件参数2.1.传参过程中获取Event 3.事件修饰符3.1.阻止默认事件阻止事件冒泡 1.事件处理 我们可以使用v-on指令&#xff08;简写为&#xff09;来监听DOM事件&#xff0c;并在事件触发时执行对应的JavaScript。 用法&#xff1a;v-o…

ubuntu服务器上安装KVM虚拟化

今天想着在ubuntu上来安装一个windwos操作系统&#xff0c;原因是因为我们楼上有几台不错的服务器&#xff0c;但是都是linux系统的。 今天我想着要给同事们搭建一个chatgpt环境&#xff0c;用来开发程序&#xff0c;但是ubuntu上其实也可以安装我嫌麻烦&#xff0c;刚好想折腾…

VMware16 pro 安装openEuler-23.09-x86_64,详细操作流程+详图。

1.环境&#xff1a; win11, vmware16 pro, openEuler-23.09-x86_64-dvd.iso 社区版openEuler 23.09官方下载地址&#xff1a; openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、…

【教学类-35-07】17号的字帖(二)班级字帖“大4”(A4竖版1份)

作品展示 背景需求&#xff1a; 大4班17号孩子练习数字书写&#xff0c;上一次是“17”号&#xff0c;这次是大“4”。 【教学类-35-05】17号的学号字帖&#xff08;A4竖版1份&#xff09;-CSDN博客文章浏览阅读440次&#xff0c;点赞6次&#xff0c;收藏7次。【教学类-35-05…

Vue2从源码角度来回答一些常见的问题

1.请说一下Vue2响应式数据的理解&#xff08;先知道基本的问题在哪里&#xff0c;源码的角度来回答&#xff0c;用的时候会有哪些问题&#xff09; 可以监控一个数据的修改和获取操作。针对对象格式会给每个对象的属性进行劫持 Object.defineProperty 源码层面 initData ->…

在香橙派5 Plus上搭建Gitlab

作为一个码农&#xff0c;一定知道Github这个最大的成人交友网站。但是Github在国内不稳定&#xff0c;经常拉不下来代码&#xff0c;也就无法推送代码。为了更方便的使用&#xff0c;顺便更好地了解Git工具&#xff0c;决定在香橙派5 Plus上搭建一个属于自己的代码仓库。 1、…

k8s的二进制部署: 源码包部署-----node节点部署

服务器IP软件包k8s--master0120.0.0.61kube-aplserver&#xff0c;kube-controer-manager&#xff0c;kube-scheduler&#xff0c;etcdk8s--master0220.0.0.62kube-controer-manager&#xff0c;kube-schedulernode节点0120.0.0.62kubelet&#xff0c;kube-proxy&#xff0c;et…

MongoDB 根据 _id 获取记录的创建时间并回填记录中

1、单条更新 MongoDB 集合 test1,有字段 _id&#xff0c;createTime&#xff0c;createTimeStr&#xff0c;name字段 &#xff0c; 查询createTime不为空的&#xff0c;根据 _id 生成该条记录的创建时间时间戳并填写到字段 createTime 字段中 &#xff0c;并打印时间戳…

IDEA快捷使用-快捷键模板

常用快捷模板 .方法的使用,例如输入 arr.null 回车 其他常规方法直接输入回车&#xff0c;不需要对象通过.来调用。 创建变量 psfi 创建公开int类型常量 public static final int prsf 创建 私有静态变量 private static final psf 创建公开静态变量 public static final创…

【问题系列】同时管理多版本node方案

目录 一、问题描述 二、解决方案 三、详细步骤 3.1 安装NVM&#xff1a; 3.2 运行NVM 3.3 安装Node.js 3.4 切换Node.js版本 3.5 验证安装&#xff1a; 四、拓展 4.1 设置默认 Node.js 版本 4.2 列出已安装的 Node.js 版本 4.3 其他命令介绍 一、问题描述 需要运行…

C#实现串口通讯

1、官网下载Launch Virtual Serial Port Driver Virtual Serial Port Driver - create and emulate virtual COM port&#xff0c;开个虚拟串口&#xff1a; Pair模式&#xff08;一对&#xff0c;成双成对的意思&#xff0c;就是COM1向COM2传或者COM2向COM1,好比两台机器的CO…

软件工程期末复习

● 用例&#xff1a;借书 ●参与者&#xff1a;管理员,借阅者 ●操作流&#xff1a; ① 管理员进入图书借阅界面&#xff0c;用例开始。 ② 系统要求输入借阅者的借书证编码。 ③系统检验借书证编码,如果正确,则显示借阅者的信息。 A1&#xff1a;借书证编码有错。 A2: 如果该借…

巨量引擎大众消费发布“十佳好课”榜单:涵盖五大行业 助力商家进阶

2023&#xff0c;中国消费市场出现温和复苏态势&#xff0c;在不确定市场环境下&#xff0c;大众消费商家如何用好科学营销手段&#xff0c;实现确定性增长?如何紧跟平台趋势&#xff0c;把握生意增长先机? 为了给商家持续提供前沿适配的营销方法、解决实际生意卡点&#xff…

MYSQL一一函数一一字符串函数

嘿嘿大家好我回来啦&#xff0c;今天我们要学习的是MYSQL中的函数&#xff0c;函数呢我们又分为字符串函数&#xff0c;数值函数&#xff0c;日期函数&#xff0c;流程函数来介绍&#xff0c;今天重点介绍字符串函数(从小题到案例方便你们更加深入的理解) 函数指的是一段可以直…