http://write.blog.csdn.net/postedit/41129935
首先不懂什么是interface的可以参考这里
http://blog.csdn.net/nvd11/article/details/18888415
不过上面的博文只是简单介绍了interface的语法和用法. 对Interface的用途并没有介绍清楚. 本文就是1个补充.
一. 对接口的三个疑问
很多初学者都大概清楚interface是1个什么, 我们可以定义1个接口, 然后在里面定义一两个常量(static final) 或抽象方法.
然后以后写的类就可以实现这个接口, 重写里面的抽象方法.
很多人说接口通常跟多态性一起存在.
接口的用法跟抽象类有点类似.
但是为何要这么做呢.
1.为什么不直接在类里面写对应的方法, 而要多写1个接口(或抽象类)?
2.既然接口跟抽象类差不多, 什么情况下要用接口而不是抽象类.
3. 为什么interface叫做接口呢? 跟一般范畴的接口例如usb接口, 显卡接口有什么联系呢?
二. 接口引用可以指向实现该接口的对象
我们清楚接口是不可以被实例化, 但是接口引用可以指向1个实现该接口的对象.
也就是说.
假如类A impletments 了接口B
那么下面是合法的:
- B b = new A();
B b = new A();
也可以把A的对象强制转换为 接口B的对象
- A a = new A90;
- B b = (B)a;
A a = new A90; B b = (B)a;
这个特性是下面内容的前提.
三. 抽象类为了多态的实现.
第1个答案十分简单, 就是为了实现多态.
下面用详细代码举1个例子.
先定义几个类,
动物(Animal) 抽象类
爬行动物(Reptile) 抽象类 继承动物类
哺乳动物(Mammal) 抽象类 继承动物类
山羊(Goat) 继承哺乳动物类
老虎(Tiger) 继承哺乳动物类
兔子(Rabbit) 继承哺乳动物类
蛇(Snake) 继承爬行动物类
农夫(Farmer) 没有继承任何类 但是农夫可以给Animal喂水(依赖关系)
它们的关系如下图:
3.1 Animal类
这个是抽象类, 显示也没有"动物" 这种实体
类里面包含3个抽象方法.
1. 静态方法getName()
2. 移动方法move(), 因为动物都能移动. 但是各种动物有不同的移动方法, 例如老虎和山羊会跑着移动, 兔子跳着移动, 蛇会爬着移动.
作为抽象基类, 我们不关心继承的实体类是如何移动的, 所以移动方法move()是1个抽象方法. 这个就是多态的思想.
3. 喝水方法drink(), 同样, 各种动物有各种饮水方法. 这个也是抽象方法.
代码:
- abstract class Animal{
- public abstract String getName();
- public abstract void move(String destination);
- public abstract void drink();
- }
abstract class Animal{ public abstract String getName(); public abstract void move(String destination); public abstract void drink(); }
3.2 Mammal类
这个是继承动物类的哺乳动物类, 后面的老虎山羊等都继承自这个类.
Mammal类自然继承了Animal类的3个抽象方法, 实体类不再用写其他代码.
- abstract class Mammal extends Animal{
- }
abstract class Mammal extends Animal{ }
3.3 Reptile类
这个是代表爬行动物的抽象类, 同上, 都是继承自Animal类.
- abstract class Reptile extends Animal{
- }
abstract class Reptile extends Animal{ }
3.4 Tiger类
老虎类就是1个实体类, 所以它必须重写所有继承自超类的抽象方法, 至于那些方法如何重写, 则取决于老虎类本身.
- class Tiger extends Mammal{
- private static String name = "Tiger";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Goat moved to " + destination + ".");
- }
- public void drink(){
- System.out.println("Goat lower it's head and drink.");
- }
- }
class Tiger extends Mammal{ private static String name = "Tiger"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Goat moved to " + destination + "."); } public void drink(){ System.out.println("Goat lower it's head and drink."); } }
如上, 老虎的移动方法很普通, 低头喝水.
3.5 Goat类 和 Rabbit类
这个两个类与Tiger类似, 它们都继承自Mammal这个类.
- class Goat extends Mammal{
- private static String name = "Goat";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Goat moved to " + destination + ".");
- }
- public void drink(){
- System.out.println("Goat lower it's head and drink.");
- }
- }
class Goat extends Mammal{ private static String name = "Goat"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Goat moved to " + destination + "."); } public void drink(){ System.out.println("Goat lower it's head and drink."); } }
兔子: 喝水方法有点区别
- class Rabbit extends Mammal{
- private static String name = "Rabbit";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Rabbit moved to " + destination + ".");
- }
- public void drink(){
- System.out.println("Rabbit put out it's tongue and drink.");
- }
- }
class Rabbit extends Mammal{ private static String name = "Rabbit"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Rabbit moved to " + destination + "."); } public void drink(){ System.out.println("Rabbit put out it's tongue and drink."); } }
3.6 Snake类
蛇类继承自Reptile(爬行动物)
移动方法和喝水方法都跟其他3动物有点区别.
- class Snake extends Reptile{
- private static String name = "Snake";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Snake crawled to " + destination + ".");
- }
- public void drink(){
- System.out.println("Snake dived into water and drink.");
- }
- }
class Snake extends Reptile{ private static String name = "Snake"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Snake crawled to " + destination + "."); } public void drink(){ System.out.println("Snake dived into water and drink."); } }
3.7 Farmer 类
Farmer类不属于 Animal类族, 但是Farmer农夫可以给各种动物, 喂水.
Farmer类有2个关键方法, 分别是
bringWater(String destination) -> 把水带到某个地点
另1个就是feedWater了,
feedWater这个方法分为三步:
首先是农夫带水到饲养室,(bringWater())
接着被喂水动物走到饲养室,(move())
接着动物喝水(drink())
Farmer可以给老虎喂水, 可以给山羊喂水, 还可以给蛇喂水, 那么feedWater()里的参数类型到底是老虎,山羊还是蛇呢.
实际上因为老虎,山羊, 蛇都继承自Animal这个类, 所以feedWater里的参数类型设为Animal就可以了.
Farmer类首先叼用bringWater("饲养室"),
至于这个动物是如何走到饲养室和如何喝水的, Farmer类则不用关心.
因为执行时, Animal超类会根据引用指向的对象类型不同 而 指向不同的被重写的方法. 这个就是多态的意义.
代码如下:
- class Farmer{
- public void bringWater(String destination){
- System.out.println("Farmer bring water to " + destination + ".");
- }
- public void feedWater(Animal a){ // polymorphism
- this.bringWater("Feeding Room");
- a.move("Feeding Room");
- a.drink();
- }
- }
class Farmer{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination + "."); } public void feedWater(Animal a){ // polymorphism this.bringWater("Feeding Room"); a.move("Feeding Room"); a.drink(); } }
3.7 执行农夫喂水的代码.
下面的代码是1个农夫依次喂水给一只老虎, 一只羊, 以及一条蛇
- public static void f(){
- Farmer fm = new Farmer();
- Snake sn = new Snake();
- Goat gt = new Goat();
- Tiger tg = new Tiger();
- fm.feedWater(sn);
- fm.feedWater(gt);
- fm.feedWater(tg);
- }
public static void f(){ Farmer fm = new Farmer(); Snake sn = new Snake(); Goat gt = new Goat(); Tiger tg = new Tiger(); fm.feedWater(sn); fm.feedWater(gt); fm.feedWater(tg); }
农夫只负责带水过去制定地点, 而不必关心老虎, 蛇, 山羊它们是如何过来的. 它们如何喝水. 这些农夫都不必关心.
只需要调用同1个方法feedWater.
执行结果:
- [java] Farmer bring water to Feeding Room.
- [java] Snake crawled to Feeding Room.
- [java] Snake dived into water and drink.
- [java] Farmer bring water to Feeding Room.
- [java] Goat moved to Feeding Room.
- [java] Goat lower it's head and drink.
- [java] Farmer bring water to Feeding Room.
- [java] Goat moved to Feeding Room.
- [java] Goat lower it's head and drink.
[java] Farmer bring water to Feeding Room. [java] Snake crawled to Feeding Room. [java] Snake dived into water and drink. [java] Farmer bring water to Feeding Room. [java] Goat moved to Feeding Room. [java] Goat lower it's head and drink. [java] Farmer bring water to Feeding Room. [java] Goat moved to Feeding Room. [java] Goat lower it's head and drink.
不使用多态的后果?:
而如果老虎, 蛇, 山羊的drink() 方法不是重写自同1个抽象方法的话, 多态就不能实现.
农夫类就可能要根据参数类型的不同而重载很多个 feedWater()方法了.
而且每增加1个类(例如 狮子Lion)
就需要在农夫类里增加1个feedWater的重载方法 feedWater(Lion l)...
而接口跟抽象类类似,
这个就回答了不本文第一个问题.
1.为什么不直接在类里面写对应的方法, 而要多写1个接口(或抽象类)?
四. 抽象类解决不了的问题.
既然抽象类很好地实现了多态性, 那么什么情况下用接口会更加好呢?
对于上面的例子, 我们加一点需求.
Farmer 农夫多了1个技能, 就是给另1个动物喂兔子(囧).
BringAnimal(Animal a, String destination) 把兔子带到某个地点...
feedAnimal(Animal ht, Animal a) 把动物a丢给动物ht
注意农夫并没有把兔子宰了, 而是把小动物(a)丢给另1个被喂食的动物(ht).
那么问题来了, 那个动物必须有捕猎这个技能. 也就是我们要给被喂食的动物加上1个方法(捕猎) hunt(Animal a).
但是现实上不是所有动物都有捕猎这个技能的, 所以我们不应该把hunt(Animal a)方法加在Goat类和Rabbit类里, 只加在Tiger类和Snake类里.
而且老虎跟蛇的捕猎方法也不一样, 则表明hunt()的方法体在Tiger类里和Snake类里是不一样的.
下面有3个方案.
1. 分别在Tiger类里和Snake类里加上Hunt() 方法. 其它类(例如Goat) 不加.
2. 在基类Animal里加上Hunt()抽象方法. 在Tiger里和Snake里重写这个Hunt() 方法.
3. 添加肉食性动物这个抽象类.
先来说第1种方案.
这种情况下, Tiger里的Hunt(Animal a)方法与 Snake里的Hunt(Animal a)方法毫无关联. 也就是说不能利用多态性.
导致Farm类里的feedAnimal()方法需要分别为Tiger 与 Snake类重载. 否决.
第2种方案:
如果在抽象类Animal里加上Hunt()方法, 则所有它的非抽象派生类都要重写实现这个方法, 包括 Goat类和 Rabbit类.
这是不合理的, 因为Goat类根本没必要用到Hunt()方法, 造成了资源(内存)浪费.
第3种方案:
加入我们在哺乳类动物下做个分叉, 加上肉食性哺乳类动物, 非肉食性哺乳动物这两个抽象类?
首先,
肉食性这种分叉并不准确, 例如很多腐蚀性动物不会捕猎, 但是它们是肉食性.
其次
这种方案会另类族图越来越复杂, 假如以后再需要辨别能否飞的动物呢, 增加飞翔 fly()这个方法呢? 是不是还要分叉?
再次,
很现实的问题, 在项目中, 你很可能没机会修改上层的类代码, 因为它们是用Jar包发布的, 或者你没有修改权限.
这种情况下就需要用到接口了.
五.接口与多态 以及 多继承性.
上面的问题, 抽象类解决不了, 根本问题是Java的类不能多继承.
因为Tiger类继承了动物Animal类的特性(例如 move() 和 drink()) , 但是严格上来将 捕猎(hunt())并不算是动物的特性之一. 有些植物, 单细胞生物也会捕猎的.
所以Tiger要从别的地方来继承Hunt()这个方法. 接口就发挥作用了.
修改后的UML图如下:
5.1 Huntable接口
由UML图可知,
我们增加了1个Huntable接口.
接口里有1个方法hunt(Animal a), 就是捕捉动物, 至于怎样捕捉则由实现接口的类自己决定.
代码:
- interface Huntable{
- public void hunt(Animal a);
- }
interface Huntable{ public void hunt(Animal a); }
5.2 Tiger 类
既然定义了1个Huntable(可以捕猎的)接口.
Tiger类就要实现这个接口并重写接口里hunt()方法.
- class Tiger extends Mammal implements Huntable{
- private static String name = "Tiger";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Goat moved to " + destination + ".");
- }
- public void drink(){
- System.out.println("Goat lower it's head and drink.");
- }
- public void hunt(Animal a){
- System.out.println("Tiger catched " + a.getName() + " and eated it");
- }
- }
class Tiger extends Mammal implements Huntable{ private static String name = "Tiger"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Goat moved to " + destination + "."); } public void drink(){ System.out.println("Goat lower it's head and drink."); } public void hunt(Animal a){ System.out.println("Tiger catched " + a.getName() + " and eated it"); } }
5.3 Snake类
同样:
- class Snake extends Reptile implements Huntable{
- private static String name = "Snake";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Snake crawled to " + destination + ".");
- }
- public void drink(){
- System.out.println("Snake dived into water and drink.");
- }
- public void hunt(Animal a){
- System.out.println("Snake coiled " + a.getName() + " and eated it");
- }
- }
class Snake extends Reptile implements Huntable{ private static String name = "Snake"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Snake crawled to " + destination + "."); } public void drink(){ System.out.println("Snake dived into water and drink."); } public void hunt(Animal a){ System.out.println("Snake coiled " + a.getName() + " and eated it"); } }
可见同样实现接口的hunt()方法, 但是蛇与老虎的捕猎方法是有区别的.
5.4 Farmer类
这样的话. Farmer类里的feedAnimal(Animal ht, Animal a)就可以实现多态了.
- class Farmer{
- public void bringWater(String destination){
- System.out.println("Farmer bring water to " + destination + ".");
- }
- public void bringAnimal(Animal a,String destination){
- System.out.println("Farmer bring " + a.getName() + " to " + destination + ".");
- }
- public void feedWater(Animal a){
- this.bringWater("Feeding Room");
- a.move("Feeding Room");
- a.drink();
- }
- public void feedAnimal(Animal ht , Animal a){
- this.bringAnimal(a,"Feeding Room");
- ht.move("Feeding Room");
- Huntable hab = (Huntable)ht;
- hab.hunt(a);
- }
- }
class Farmer{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination + "."); } public void bringAnimal(Animal a,String destination){ System.out.println("Farmer bring " + a.getName() + " to " + destination + "."); } public void feedWater(Animal a){ this.bringWater("Feeding Room"); a.move("Feeding Room"); a.drink(); } public void feedAnimal(Animal ht , Animal a){ this.bringAnimal(a,"Feeding Room"); ht.move("Feeding Room"); Huntable hab = (Huntable)ht; hab.hunt(a); } }
关键是这一句
- Huntable hab = (Huntable)ht;
Huntable hab = (Huntable)ht;
本文一开始讲过了, 接口的引用可以指向实现该接口的对象.
当然, 如果把Goat对象传入Farmer的feedAnimal()里就会有异常, 因为Goat类没有实现该接口. 上面那个代码执行失败.
如果要避免上面的问题.
可以修改feedAnimal方法:
- public void feedAnimal(Huntable hab, Animal a){
- this.bringAnimal(a,"Feeding Room");
- Animal ht = (Animal)hab;
- ht.move("Feeding Room");
- hab.hunt(a);
- }
public void feedAnimal(Huntable hab, Animal a){ this.bringAnimal(a,"Feeding Room"); Animal ht = (Animal)hab; ht.move("Feeding Room"); hab.hunt(a); }
这样的话, 传入的对象就必须是实现了Huntable的对象, 如果把Goat放入就回编译报错.
但是里面一样有一句强制转换
- Animal ht = (Animal)hab
Animal ht = (Animal)hab
反而更加不安全, 因为实现的Huntable的接口的类不一定都是Animal的派生类.
相反, 接口的出现就是鼓励多种不同的类实现同样的功能(方法)
例如,假如一个机械类也可以实现这个接口, 那么那个机械就可以帮忙打猎了(囧)
1个植物类(例如捕蝇草),实现这个接口, 也可以捕猎苍蝇了.
也就是说, 接口不会限制实现接口的类的类型.
执行输出:
- [java] Farmer bring Rabbit to Feeding Room.
- [java] Snake crawled to Feeding Room.
- [java] Snake coiled Rabbit and eated it
- [java] Farmer bring Rabbit to Feeding Room.
- [java] Goat moved to Feeding Room.
- [java] Tiger catched Rabbit and eated it
[java] Farmer bring Rabbit to Feeding Room. [java] Snake crawled to Feeding Room. [java] Snake coiled Rabbit and eated it [java] Farmer bring Rabbit to Feeding Room. [java] Goat moved to Feeding Room. [java] Tiger catched Rabbit and eated it
这样, Tiger类与Snake类不但继承了Animal的方法, 还继承(实现)了接口Huntable的方法, 一定程度上弥补java的class不支持多继承的特点.
六.接口上应用泛型.
上面的Huntable里还是有点限制的,
就是它里面的hunt()方法的参数是 Animal a, 也就是说这个这个接口只能用于捕猎动物.
但是在java的世界里, 接口里的方法(行为)大多数是与类的类型无关的.
也就是说, Huntable接口里的hunt()方法里不单只可以捕猎动物, 还可以捕猎其他东西(例如 捕猎植物... 敌方机械等)
6.1 Huntable接口
首先要在Huntable接口上添加泛型标志:<T>
- interface Huntable<T>{
- public void hunt(T o);
- }
interface Huntable<T>{ public void hunt(T o); }
然后里面的hunt()的参数的类型就写成T, 表示hunt()方法可以接受多种参数, 取决于实现接口的类.
6.2 Tiger类(和Snake类)
同样, 定义tiger类时必须加上接口的泛型标志<Animal>, 表示要把接口应用在Animal这种类型.
- class Tiger extends Mammal implements Huntable<Animal>{
- private static String name = "Tiger";
- public String getName(){
- return this.name;
- }
- public void move(String destination){
- System.out.println("Goat moved to " + destination + ".");
- }
- public void drink(){
- System.out.println("Goat lower it's head and drink.");
- }
- public void hunt(Animal a){
- System.out.println("Tiger catched " + a.getName() + " and eated it");
- }
- }
class Tiger extends Mammal implements Huntable<Animal>{ private static String name = "Tiger"; public String getName(){ return this.name; } public void move(String destination){ System.out.println("Goat moved to " + destination + "."); } public void drink(){ System.out.println("Goat lower it's head and drink."); } public void hunt(Animal a){ System.out.println("Tiger catched " + a.getName() + " and eated it"); } }
这样, 在里面hunt()参数就可以指明类型Animal了, 表示老虎虽然有捕猎这个行为, 但是只能捕猎动物.
七.什么情况下应该使用接口而不用抽象类.
好了, 回到本文最重要的一个问题.
做个总结
1. 需要实现多态
2. 要实现的方法(功能)不是当前类族的必要(属性).
3. 要为不同类族的多个类实现同样的方法(功能).
下面是分析:
7.1 需要实现多态
很明显, 接口其中一个存在意义就是为了实现多态. 这里不多说了.
而抽象类(继承) 也可以实现多态
7.2. 要实现的方法(功能)不是当前类族的必要(属性).
上面的例子就表明, 捕猎这个方法不是动物这个类必须的,
在动物的派生类中, 有些类需要, 有些不需要.
如果把捕猎方法卸载动物超类里面是不合理的浪费资源.
所以把捕猎这个方法封装成1个接口, 让派生类自己去选择实现!
7.3. 要为不同类族的多个类实现同样的方法(功能).
上面说过了, 其实不是只有Animal类的派生类才可以实现Huntable接口.
如果Farmer实现了这个接口, 那么农夫自己就可以去捕猎动物了...
我们拿另个常用的接口Comparable来做例子.
这个接口是应用了泛型,
首先, 比较(CompareTo) 这种行为很难界定适用的类族, 实际上, 几乎所有的类都可以比较.
比如 数字类可以比较大小, 人类可以比较财富, 动物可以比较体重等.
所以各种类都可以实现这个比较接口.
一旦实现了这个比较接口. 就可以开启另1个隐藏技能:
就是可以利用Arrays.sort()来进行排序了.
就如实现了捕猎的动物,
可以被农夫Farmer喂兔子一样...
八.接口为什么会被叫做接口, 跟真正的接口例如usb接口有联系吗?
对啊, 为什么叫接口, 而不叫插件(plugin)呢, 貌似java接口的功能更类似1个插件啊.
插上某个插件, 就有某个功能啊.
实际上, 插件与接口是相辅相成的.
例如有1个外部存储插件(U盘), 也需要使用设备具有usb接口才能使用啊.
再举个具体的例子.
个人电脑是由大型机发展而来的
大型机->小型机->微机(PC)
而笔记本是继承自微机的.
那么问题来了.
对于, 计算机的CPU/内存/主板/独显/光驱/打印机 有很多功能(方法/行为), 那么到底哪些东西是继承, 哪些东西是接口呢.
首先, cpu/内存/主板 是从大型机开始都必备的, 任何计算机都不能把它们去掉.
所以, 这三样东西是继承的, 也就说笔记本的cpu/内存/主板是继承自微机(PC)的
但是/光驱/呢, 现实上很多超薄笔记本不需要光驱的功能.
如果光驱做成继承, 那么笔记本就必须具有光驱, 然后屏蔽光驱功能, 那么这台笔记本还能做到超薄吗? 浪费了资源.
所以光驱,打印机这些东西就应该做成插件.
然后, 在笔记本上做1个可以插光驱和打印机的接口(usb接口).
也就是说, PC的派生类, 有些(笔记本)可以不实现这个接口, 有些(台式机)可以实现这个接口,只需要把光驱插到这个接口上.
至于光驱是如何实现的,
例如一些pc派生类选择实现蓝光光驱, 有些选择刻录机. 但是usb接口本身并不关心. 取决与实现接口的类.
这个就是现实意义上的多态性啊.
相关推荐
亲测可用
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
IDE护眼主题套件
内容概要:文章详细介绍了基于Matlab/Simulink构建的增程式电动车仿真模型。该模型由电池、电机、发动机、整车动力学、控制策略和驾驶员模块六大组件构成,重点在于各模块间的能量流动逻辑。文中特别强调了功率跟随控制策略,通过PID闭环控制使发动机功率与电池需求动态匹配,优化了燃油经济性和SOC控制精度。此外,模型采用开放式架构,所有参数通过m脚本集中管理,便于修改和扩展。文章展示了模型在典型工况下的性能表现,并突出了其在科研和工程应用中的灵活性和实用性。; 适合人群:对新能源汽车技术感兴趣的工程师、研究人员以及高校相关专业师生。; 使用场景及目标:①用于研究增程式电动车的能量管理策略;②作为教学案例帮助学生理解复杂系统的建模方法;③为实际工程项目提供可复用的仿真平台。; 阅读建议:读者应重点关注模型的架构设计和关键控制算法实现,同时结合提供的代码片段进行实践操作,以便更好地掌握增程式电动车的工作原理及其优化方法。
51a30-main.zip
内容概要:本文详细介绍了多种类型的数据库索引及其应用场景,包括普通索引、唯一性索引、单个索引、复合索引、聚簇索引、非聚簇索引、主索引、外键索引、全文索引和空间索引。每种索引都有其独特的定义、要点和适用场景,并附有具体的SQL代码示例。此外,文章还对比了InnoDB和MyISAM两种存储引擎的特点,解释了脏读、不可重复读、可重复读和幻读的概念,并讨论了SQL优化的方法以及数据库事务的ACID特性。 适合人群:具备一定数据库基础知识的开发者、数据库管理员以及参与数据库设计和优化的技术人员。 使用场景及目标:①帮助开发者选择合适的索引类型以提高查询效率;②理解不同存储引擎的特点,选择最适合应用场景的存储引擎;③掌握事务隔离级别的概念,避免数据不一致问题;④学习SQL优化技巧,提升数据库性能;⑤理解ACID特性,确保数据库操作的一致性和可靠性。 阅读建议:本文内容较为全面且深入,建议读者结合实际项目需求,重点理解不同类型索引的应用场景,掌握SQL优化的基本原则,并熟悉事务处理的最佳实践。
内容概要:本文详细介绍了MATLAB中优化算法的实现方法,涵盖确定性算法(如梯度下降法)和随机性算法(如遗传算法、粒子群优化)。文章首先讲解了梯度下降法和MATLAB优化工具箱的应用,展示了如何使用fmincon解决约束优化问题。接着,文章深入探讨了线性规划、非线性规划和多目标优化的理论和实践,提供了具体的MATLAB代码示例。此外,文中还介绍了遗传算法、粒子群优化和模拟退火算法的原理及应用,并通过实例展示了这些算法在实际问题中的使用。最后,文章讨论了优化算法在工程、金融和机器学习领域的高级应用,以及调试和优化的常见策略。 适合人群:具备一定编程基础,对优化算法感兴趣的工程师、研究人员和学生。 使用场景及目标:①理解优化算法的基础理论和实现方法;②掌握MATLAB优化工具箱的使用,解决线性、非线性、多目标优化问题;③学习遗传算法、粒子群优化和模拟退火算法的具体应用;④提高优化算法的性能和可靠性,解决实际工程、金融和机器学习问题。 阅读建议:本文内容丰富,涉及多种优化算法及其MATLAB实现,建议读者先掌握基本的优化理论和MATLAB编程基础,再逐步深入学习各类算法的具体应用。在学习过程中,结合提供的代码示例进行实践,并尝试调整参数以优化算法性能。
this is for myself learn coding, change a pc debug.
项目资源包含:可运行源码+sql文件 适用人群:学习不同技术领域的小白或进阶学习者;可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 项目具有较高的学习借鉴价值,也可拿来修改、二次开发。 有任何使用上的问题,欢迎随时与博主沟通,博主看到后会第一时间及时解答。 开发语言:Python 框架:django Python版本:python3.8 数据库:mysql 5.7 数据库工具:Navicat 开发软件:PyCharm 浏览器:谷歌浏览器
【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
内容概要:本文深入探讨了MMC型STATCOM/SVG的核心技术和调试技巧,重点讲解了载波移相调制(CPS-PWM)和电压均衡控制两大关键技术。载波移相调制通过为每个子模块设置不同的载波相位差,有效降低谐波含量并优化开关频率。电压均衡则分为桥臂内、桥臂间和相间三个层次,分别采用动态排序、比例控制和零序电压注入等方法,确保系统稳定运行。文章还分享了多个实战经验,如低压调试、红外热像仪检测以及避免参数设置不当引发的问题。; 适合人群:从事电力电子领域,特别是参与STATCOM/SVG项目的设计、开发和调试的技术人员。; 使用场景及目标:①理解MMC型STATCOM/SVG的工作原理和技术细节;②掌握载波移相调制的具体实现方法;③学习电压均衡控制的各种策略及其应用场景;④获取实际调试过程中常见问题的解决方案。; 阅读建议:本文涉及大量技术细节和实战经验,建议读者结合实际项目进行阅读,重点关注载波移相调制和电压均衡控制的具体实现,并参考提供的代码片段进行实践。
liangmmm_finalll.scdoc
内容概要:本文详细介绍了Solidity语言的核心概念和语法特性,涵盖结构体、函数修改器、事件、类型系统、数组、映射、操作符、合约可见性、构造函数、抽象合约、接口、继承、控制结构、异常处理和keccak256哈希函数等内容。通过这些知识点的讲解,帮助开发者理解如何构建高效、安全的智能合约。; 适合人群:对区块链开发感兴趣,尤其是希望深入了解以太坊智能合约开发的初学者及有一定编程基础的研发人员。; 使用场景及目标:①掌握Solidity语言的基本语法和高级特性,如结构体、函数修改器、事件等;②理解合约的可见性、继承、接口等面向对象编程特性;③学会使用keccak256等安全机制保障智能合约的安全性;④能够运用控制结构和异常处理编写健壮的合约逻辑。; 阅读建议:建议读者从基础语法开始逐步深入,结合实际案例进行练习。尤其要注意合约的安全性和性能优化,避免常见的漏洞和错误。在学习过程中,应多参考官方文档和其他优质资料,不断巩固和拓展知识体系。
原型模式课上代码.zip
内容概要:文章介绍了利用Simulink搭建锂电池组主动均衡系统的原理与实现方法。通过双向DC-DC主动均衡电路和模糊控制算法,解决了储能项目中电池包SOC(荷电状态)差异过大的问题。文中详细解释了关键代码逻辑,包括均衡状态切换、模糊控制器规则配置以及动态子系统使能技术的应用。特别提到当SOC最大差值超过设定阈值时,系统会自动启动均衡,并根据差值大小智能调整均衡电流。仿真结果显示,在处理突发状况(如某电池SOC突然下降)时,该系统能在短时间内恢复平衡。此外,文章还分享了调试过程中的一些实用技巧,如设置合理的均衡电流限值。; 适合人群:从事锂电池管理系统研发的技术人员,尤其是有一定MATLAB/Simulink使用经验的工程师。; 使用场景及目标:①解决储能系统中锂电池组SOC不一致的问题;②优化现有均衡策略,提高均衡效率;③学习如何在Simulink中实现复杂控制算法。; 其他说明:本文不仅提供了详细的代码示例和技术细节,还通过生动的比喻帮助读者更好地理解复杂的控制逻辑。建议读者在实践中结合理论知识进行调试和验证。
【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。