Java OOP--面向对象

OOP

面向对象的三大特征:封装,继承,多态。

封装

将客观客观事物封装成一个抽象的类,将其属性与方法组合在一起,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的隐藏其具体实现。

继承

通过扩展一个现有类建立一个新类,这个扩展后的新类具有被扩展类的所有属性和方法(处隐藏了的外)。通过继承创建的新类称为“子类”或者“派生类”,被继承的类称为“父类”或者"超类"。

多态

一个实体的多种形态,是允许将父对象设置为可以和他的子对象相等的技术,赋值之后父对象可以根据当前赋值给他的子对象的特征以不同的方式运作。就是允许将子类类型的指针赋值给父类类型的指针;
实现多态的方式有覆盖(重写)和重载:
覆盖(重写):子类重新定义父类的虚函数;
重载:允许存在多个同名函数,而这些函数的参数列表不同(参数个数或者参数类型)
增强软件的灵活性和重用性

1.1类和对象

类是Java语言中最基本的单位,是一类事务的抽象,类里有方法和属性。
对象是具体的实例。

package Review;

import com.sun.security.auth.UnixNumericGroupPrincipal;

public class CreatObjectAndClass {
    public static void main(String[] args) {
    //实例化一个对象 student
       Student student1=new Student() ;
       System.out.println(student1.name);
       System.out.println("number="+student1.number);
       student1.Age(16);
       student1.SumScore(98,76);
       //实例化多个对象
        Student student2=new Student() ;
        student2.SumScore(22,44);
    }
}
//创建一个类
class Student{
    //属性
    String name;
    int age;
    int number=22;
    int math;
    int english;
    //无参方法
    public void study(){
        System.out.println("学习");
    }
    //含参方法
    public void Age(int age){
        System.out.println("今年"+age+"岁");
    }
    //返回值方法
    public int SumScore(int math,int english){
        return math+english;
    }
}

对象的三个特点:
行为:可以对对象完成哪些操作,或者对对象应用哪些方法;
状态:当调用那些方法时,对象会如何响应;
标识:区分具有相同行为和状态的不同对象;
通过class关键字创建类,通过new创建对象;

创建对象的不同方式

1.可以通过new关键字调用。但是会增加耦合度。

Hello hello=new Hello();

2.可以使用Class类里的newInstance。

 Class heroClass = Class.forName("yunche.test.Hello");
           Hello h =(Hello) heroClass.newInstance();
           h.sayWorld();

使用Constructor类的newInstance方法

 //获取类对象
          Class heroClass = Class.forName("yunche.test.Hello");
          //获取构造器
          Constructor constructor = heroClass.getConstructor();
          Hello h =(Hello) constructor.newInstance();
          h.sayWorld();

3.可以采用clone方式,对已经分配了内存的源对象进行clone,但是要想使用clone方法实现Cloneable接口。

public class Hello implements Cloneable
{
   public void sayWorld()
   {
       System.out.println("Hello world!");
   }

   public static void main(String[] args)
   {
       Hello h1 = new Hello();
       try
       {
           Hello h2 = (Hello)h1.clone();
           h2.sayWorld();
       }
       catch (CloneNotSupportedException e)
       {
           e.printStackTrace();
       }
   }
}

4.采用序列化机制,使用序列化时,要实现实现Serializable接口,将一个对象序列化到磁盘上,而采用反序列化可以将磁盘上的对象信息转化到内存中。

public class Serialize
{
    public static void main(String[] args)
    {
        Hello h = new Hello();
        //准备一个文件用于存储该对象的信息
        File f = new File("hello.obj");
        try(FileOutputStream fos = new FileOutputStream(f);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            FileInputStream fis = new FileInputStream(f);
            ObjectInputStream ois = new ObjectInputStream(fis)
            )
        {
            //序列化对象,写入到磁盘中
            oos.writeObject(h);
            //反序列化对象
            Hello newHello = (Hello)ois.readObject();
            //测试方法
            newHello.sayWorld();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}
匿名对象

没有名字的对象,是对象的简化表示形式。当被调用的对象值调用一次时使用。

//创建了一个匿名对象并调用其方法
new Demo().shoe();
1.2封装

隐藏对象的属性和实现细节,提高安全性和重用性。
private 权限修饰符进行封装,既可以封装类也可以封装方法,封装后的类和方法不能直接被外调用,只能在本类中调用。但是可以间接调用,提供公开的方法,如get()和set()。
Java中的四种权限修饰符:
public(公共的,最大权限,任何地方可访问)
protected(保护的,只能在同一个包或者其本类及子类访问)
default(可以不写,程序默认情况,本类和同包类,子类不能访问)
private(私有的,只有本类可以访问)。
在这里插入图片描述

package ClassAndObject;

public class CreatPrivate {
	public static void main(String[] args) {
		//实例化一个对象
		Studen studen=new Studen();
		//封装类里的属性不能被其对象直接访问
		//System.out.println(student.name);
		//封装类里的方法也不能被直接访问
		//student。study();
		
		//对象可以调用类的公共方法,从而间接调用其封装方法
		studen.Study();
		//用set()和get()间接调用封装属性
		studen.setname("Bob");
		System.out.println(studen.getname());
	}
}
class Studen{
	//封装属性name
	private String name="Alica";
	//封装方法study()
	private  void study() {
		System.out.println("学习封装方法");
	}
	public void Study() {
		//类本身可以调用其自身的封装方法
		study();
	}
	public void setname(String Name) {
		name=Name;
	}
	public String getname() {
		return name;
	}
}

构造方法

构造方法是一个与类同名且返回值类型为同名类类型的方法。对象的创建是通过构造方法来完成的,其主要功能是完成对象的创建或者对象的实例化。当实例化一个对象时会自动调用一个构造方法。
构造方法的参数可有可无。构造方法也可以重载。构造方法不能被子类继承,所以没法重写。但是可以重载。
如果不写构造方法,默认创建无参构造方法。要想使无参构造方法失效,可以重载含参构造方法。

格式
//可无参也可以有参
修饰符  类名(【参数】){
       代码……
}
构造方法创建对象并赋值
package ClassAndObject;
public class CreatNewMethod {
	public static void main(String[] args) {
		//a是引用变量,引用的是对象的地址值。无参函数创建的对象
		Stu a=new Stu();
		//含参函数创建的对象
		Stu b=new Stu(1);
		b.setB(12);
		System.out.println(b.getB());
	}
}
class Stu{
	int a;
	int b;
	//无参构造函数
	public Stu() {
		System.out.println("这里是无参构造函数");
	}
	public Stu(int a) {
		//含参构造方法初始化赋值
		this.a=a;
		System.out.println("这里是"+a+"个含参构造函数");
	}
	//赋值方法2
	public int getB() {
		return b;
	}
	public void setB(int b) {
		this.b = b;
	}
	
}
构造代码块

在类的内部,方法外部,的代码块。常用于抽取构造方法中的共性代码。 每次调用构造方法前都会调用构造代码块, 优先于构造方法加载。

package NewMethod;
public class NewCodeBlock {
	public static void main(String[] args) {
		Teacher t=new Teacher();
	}
}
class Teacher{
	//构造代码块
	{
		System.out.println("构造代码块");
	}
	public Teacher(){
		System.out.println("g构造方法");
	}
}
//输出结果:
//构造代码块
//g构造方法
this

局部变量的值赋值给成员变量时,若局部变量和成员变量同名,用代表本类的对象this来完成。this可以看作本类对象的一个引用对象。

package NewMethod;

public class ThisNewMethod {
	public static void main(String[] args) {
		Teache tea=new Teache();
	}
}
class Teache{
	int age;
	public Teache() {
		//this(13);//this(13)调用含参构造函数必须放在第一行
		System.out.println("无参构造函数");
		//this(12);
	}
	public Teache(int age) {
		this();//调用无参构造函数。但是不同同时调用。this()和this(13)不能同时使用
		this.age=age;
		System.out.println("含参构造函数"+age);
	}
}
1.3继承
类得继承

继承是从已有的类中派生出新的类。派生出得类可以使用父类得属性和方法,除private外。
用extends定义,java支持单继承。

package ClassAndObject;

public class SonAndFather {
	public static void main(String[] args) {
		//static方法里面只能调用static属性或者方法
		onn X=new onn();//子类对象
		onn.worki();//子类方法
		System.out.println(onn.age);
	}
}
//父类
class father{
	public static int age;
	public static String name;
	public static void worki() {
		System.out.println("工作");
	}
}
//子类
class onn extends father{
	int score;
	public static void studying(){
		System.out.println("学习");
	}
}
super

过super关键字可以使用父类的内容,可以看作父类的一个引用对象,如果用,必须出现在调用位置的第一行。

package ClassAndObject;

public class UseSuper {
	public static void main(String[] args) {
		soo xixi=new soo(33);//自动匹配无参构造
		System.out.println(xixi.ag);
	}
}
class fa{
	public  int ag;
	public fa() {
	}
	public static void as(){
		System.out.println("");
	}
}
class soo extends fa{
	//子类得构造方法,会自动调用super();
	public soo(int ag) {
		super();//自动调用隐藏了得super()方法,super()是父类得无参构造方法;必须放在第一条语句
		super.ag=ag;
	}	
}
方法的重写

1、 继承后,子类就拥有了父类的功能
2、 那么在子类中,可以添加子类特有的功能也可以修改父类的原有功能
3、 子类中方法签名与父类完全一样(包括方法的返回值,方法名和参数列表,完全一致时,会发生覆盖/复写操作,相当于修改功能
注意:
1、父类中的私有方法和构造方法不能被重写
2、子类重写父类方法时,修饰符要大于等于父类修饰符的权限

package ClassAndObject;

public class Overide {
	public static void main(String[] args) {
		erzi E=new erzi();
		//重写后的方法
		E.method1(3);
		//重写前得方法
		E.method1();
	}
}
class dady{
	public void method1() {
		System.out.println("dady");
	}
}
class erzi extends dady{
	//方法重写:子类中方法签名与父类完全一样(包括方法的返回值,方法名和参数列表,完全一致)
	public void method1(int a) {
		System.out.println(a);
	}
}
继承中的构造方法

子类创建对象时,默认去访问父类的无参构造方法。
在构造方法的第一行,都有一条默认语句:super();
父类没有无参构造函数时,可以用super调用父类的其他构造函数。

this和super的区别

1.this代表本类对象的引用,super代表父类对象的引用。
2.this常用于区分局部变量和成员变量,super用于区分父类成员和本类成员。
3.this和super不可以同时出现在同一个构造方法里,他们只要出现都必须放在第一行,同时出现的话会矛盾。

重写和重载的区别

重载:是指同一个类中的多个方法具有想用的名字,饭这些方法具有不同的参数列表,即参数的数量或者参数类型不能完全相同。一个类中多态性的一种表现。
重写:是存在父子类之间的,子类定义的方法与父类的方法具有相同的方法名字,相同的参数列表和相同的返回类型,是子类与父类之间多态性的一种表现。

static

修饰成员变量和成员方法得关键字,只加载一次,会一直存在,不再开辟新空间,全局唯一,全局共享。随着类得加载而加载,优先于对象加载,可以直接被类名调用,静态只能调静态,非静态可以随意调用。static不能和this或super公用,因为有static时可能还没有对象。

package ClassAndObject;

public class SeeStatic {
	public static void main(String[] args) {
		System.out.println(fat.a);//可以先与创建对象前通过类名直接访问静态属性
		s sa=new s();
		sa.eat();
		sa.sleep();
	}
}
class fat{
	public static int a=99;
	public int b=98;
	public void eat() {//非静态都可以访问
		System.out.println(b);
		System.out.println(a);
	}
	public static void sleep() {
		//System.out.println(b);静态方法不能访问非静态
		System.out.println(a);//非静态可以访问非静态
	}
}
class s extends fat{
//	public void eat() {
//		System.out.println("eat");
//	}
	//若子类里没有匹配得方法则去父类方法里寻找
}
静态变量和实例变量

静态变量前要加static关键字,实例变量不用;
实例变量属于某个实例对象的属性,必须创建了实例对象,其中的实例变量次啊会分配空间,才能使用这个实例变量。静态变量不属于某个实例,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建人任何实例对象,静态变量就会被分配空间,静态变量就可以被使用。

静态代码块

随着类的加载而加载,并且只被加载一次,一般用于项目的初始化
static{…}

代码块

1.普通代码块:类中方法的方法体
2.构造代码块:构造代码块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数,如果出现多个构造代码块,执行顺序有他们在代码中出现的次序决定,先出现先执行。
3.静态代码块:用static{}包裹起来的代码块,静态代码块优先于构造代码块执行。只在第一次new时执行一次,之后不在执行。静态代码块不能直接访问实例变量和实例方法,需要通过类的实例对象来访问。
4.同步代码块:使用synchronized(){}包裹起来的代码块,在多线程环境下,对共享数据的读写操作时需要互斥进行的,否则会导致数据的不一致性。同步代码块需要卸载方法中。
执行顺序: 静态 - 构造代码块 - 构造方法 - 局部

final

被final修饰的类不能被继承;
被final修饰的方法不能被重写,可以被重载;
被final修饰的变量为常量,不可以被更改;
final 数据类型 常量名=值;
子类可以通过继承修改父类,如果父类不想被修改可以是fina修饰。

1.8多态

多态是指同一个实体具有多种形式。主要指同一个对象,在不同时刻代表的对象不一样,值得是对象的多种形态。,可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码。我们可以不用关系某个对象到底是什么具体类型,就可以使用该对象大的某些方法,提高了程序的扩展性和可维护性。

由小到大,向上转型

继承是为了在不修改源代码得基础上增加新功能设定;封装是为了保护代码;多态是为了提供统一调用标准。可以把不同得子类当成父类来看,子类得方法可以千遍万化,但是只能调用从父类重写过去得方法。所以多态得前提是继承,同时要有方法得重写。在多态中编译看左边,运行看右边。

package ClassAndObject;

public class ManyStation {
	public static void main(String[] args) {
		//创建多态
		Dd Duo=new So();
		//Duo.other();不能调用父类中没有得方法
		Duo.eat();//子类重写后的方法
		System.out.println(Duo.ans);//父类的属性。成员变量使用的是父类的
	}
}
class Dd{
	public int ans=99;
	public void eat() {
			System.out.println("父类eat()");
	}
}
//多台得前提是继承
class So extends Dd{
	public int ans=3;
	public void other() {
		System.out.println("非重写方法");
	}
	public void eat() {
		System.out.println("子类方法重写");
	}
}
由大到小,向下转型

向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。
Parent p = new Child();//向上转型,此时,p是Parent类型
Child c = (Child)p;//此时,把Parent类型的p转成小类型Child
//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。

1.4 异常
异常的继承结构
Throwable-顶级父类
--Error:程序中无法处理的错误,一般标识运行时JVM出现问题。
--Exception:程序本身可以捕获并且可以处理的异常。
	--RunTimeExcetion:运行时异常(不受检异常),JVM运行期间可能出现的错误,编译器不会检查此类异常,如数组下标越界,空指针异常等
	--Other:受检异常,编译器会检查的异常,必须对该异常进行处理,否则编译不通过。
异常处理

抛出异常:
一个方法不处理这个异常,而是调用层次向上传递,谁调用这个方法,这个异常就由谁来处理。
throw:用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者出,并结束当前方法的执行。

public class DemoThrow {
    public static void main(String[] args) {
      int a =   DemoThrow.div(4,0);
      System.out.println(a);
    }
   public static int div(int a,int b)
      {
            if(b==0)
              throw new ArithmeticException("异常信息:除数不能为0");//抛出具体问题,编译时不检测
            return a/b;
     }
}

throws:用于方法声明之上,用于标识当前方法不处理异常,而是提醒该方法的调用者来处理异常。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DemoThrows {
    public static void main(String[] args) throws FileNotFoundException{
        readFile();
    }
    public static  void readFile() throws FileNotFoundException {
        InputStream is = new FileInputStream("E:/iodemo/ch01.txt");
    }
}

捕获异常

捕捉程序运行时的错误,封装起来不让用户看见。

try{

需要捕获的代码

}catch(异常类型 异常名){

处理方案

}

package ClassAndObject;

import java.util.InputMismatchException;
import java.util.Scanner;

public class useTry {
	public static void main(String[] args) {
		try {
				int a=new Scanner(System.in).nextInt();
				int b=new Scanner(System.in).nextInt();
				System.out.println(a/b);
			}
		catch(InputMismatchException aaa) {
			System.out.println("请输入整数");
		}
		catch(ArithmeticException e) {
			System.out.println("除数不能为0");
		}
		catch(Exception aaa)
		{
			System.out.println("出现错误");
		}
	}
}
1.5抽象类

没有方法体的方法叫抽象方法,含有抽象方法的类叫抽象类(抽象类也可以不含有抽象方法),抽象类用abstract修饰。
抽象类可以被继承,但是不可以被实例化。可以有其他的非抽象方法。
一个类如果继承了抽象类,要么重写其父类的所有抽象方法,从而转化成普通类,只要还有抽象方法,就会是抽象类。
abstract class A{
​ public abstract void eat();
}
abstract与private,final,static矛盾,使用private私有化后子类无法被重写,static是静态的优先于对象存在,静态方法无法被重写,被final修饰后也无法被重写。

package ClassAndObject;

public class AbtractClass {
	public static void main(String[] args) {
		Fs xxi=new Fs();
		//Fss xii=new Fss();抽象类不能被实例化
		xxi.method2();
	}
}
abstract class FF{
	abstract public void method2() ;//
}
class Fs extends FF{
	//继承抽象类需要重写所有抽象方法
	public void method2() {
		System.out.println("重写父类抽象方法");
	}
}
abstract class Fss extends FF{
	//可以增加其他的方法
	public void method3() {
		System.out.println("hahaha");
	}
}

抽象类也有构造方法,但是本身不能实例化,一般用于给子类实例化。

package ClassAbstract;
//抽象类的构造方法
public class Test2_Animal2 {
}
abstract class Animal2{
       //抽象类可以有构造方法,但是无法实例化
       //用于子类实例化
       public Animal2(){
          System.out.println("fu..Animal2()");
       }
}
class Zi2 extends Animal2{
}
class TestAnimal2{
       public static void main(String[] args) {
//           Animal2 a2 = new Animal2();//抽象类无法实例化   
//           Zi2 z=new Zi2();//创建子类实例化对象
              Animal2 a2 = new Zi2();//抽象类多用于多态    
       }
}
1.6接口

java没有多继承,如果想要实现多个类的功能,可以通过实现多个接口来实现。
通过interface关键字创建接口,implements让子类来实现,接口和类之间可以多实现,接口和接口之间可以多继承。
接口里面只有抽象方法,没有构造方法,不可实例化。在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。接口的存在是为了规范和统一标准。
接口支持多继承和多实现。实现的类只有两条路,要么重写实现的所有接口里的所有抽象方法,要么成为抽象类。
接口里面没有成员变量,都是常量,如果在接口里定义一个变量没有写修饰符时,默认会加上public static final。接口里的方法默认就是抽象的,如果不写abstract,会自动补齐。

interface Inte{//定义一个接口

public abstract void show();

}

package Inetface;

public class UseInterface {
	public static void main(String[] args) {
		
	}
}
interface Inter3{
	abstract void XXX();
}
interface Inter4{
	abstract void XXXX();
}
interface Inter0{
	abstract void XX();
}
interface Inter00{
	abstract void XXx();
}
//关键字implement 可以实现接口。且可以多实现
//实现多接口的类只能全部重写接口里的抽象类
class Inter5 implements Inter3,Inter4 {
	public void XXX() {
		 System.out.println("");
	 }
	 public void XXXX() {
		 
	 }
	 public void XXXXX() {};
}
//接口可以多继承,继承接口的还是接口,只能在新接口里面添加抽象类
interface Inter6 extends Inter3,Inter4{
	//可以继承的时候添加新抽象方法
	abstract void XXXXXX();
}
//如果只重写所有接口中的部分抽象方法,这实现的是抽象类
abstract class Inter7 implements Inter3,Inter4{
	public void XXX() {
		System.out.println("Inter3");
	}
}
//Fox实现了Inter5里面的抽象方法,同样继承了Inter0和Inter00里面的抽象方法
abstract class Fox  extends Inter5 implements Inter0,Inter00{
	
}
接口和类的区别

抽象类和接口都不能被实例化,如果要实例化,抽象类变量必须只想实现所有抽象方法的子类对象,接口变量必须只想实现所有接口方法的类对象。
抽象类要被子类继承,接口要被类实现。
接口只能做方法声明,抽象类中可以做方法申明,也可以做方法实现
接口里定义的变量只能是公共的静态常量,抽象类中的变量是普通变量。
抽象类里的方法必须被子类全部实现 ,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能是抽象类
抽象方法只能声明,不能实现,接口时设计的结果,抽象类时重构的结果。
抽象类里可以没有抽象方法,如果要扩展抽象类的新方法,子类很容易就能得到这些新方法。
如果一个类里有抽象方法,那么这个类只能是抽象类。
抽象方法要被实现,所以不能是静态类,也不能是私有的。
接口可继承接口,并可多继承接口,但类只能单根继承。

1.7设计模式

Java中有23种设计模式,本质时面向对象设计原则的实际运用,是对类的封装性,继承性和多态性以及类关联关系和组合关系的充分理解。
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。

设计模式的六大原则

1、开闭原则(Open Close Principle)
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科
3、依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
5、迪米特法则(最少知道原则)(Demeter Principle)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
原则是尽量使用合成/聚合的方式,而不是使用继承。

单例设计模式

单例模式最重要的是确保对象只有一个,控制外界创建对象的个数只能创建1个对象,简单来说,保证一个类在内存中的对象就一个,这样可节约系统内存空间,控制资源的使用。

package cn.tedu.single;
//测试单例设计模式 
public class Test8_Single {
    public static void main(String[] args) {
       Single s = Single.get();
       Single s1 = Single.get();
       //get()多少次,内存中使用的都是同一个对象
       System.out.println(s);//cn.tedu.single.Single@15db9742
       System.out.println(s1);//cn.tedu.single.Single@15db9742
    }
}
饿汉式

类加载的时候就实例化,并且创建单例对象。
开发步骤:
1、 私有化构造方法
2、 在类的内部创建好对象
3、 对外界提供一个公共的get(),返回一个已经准备好的对象

class Single{
//  1、私有化构造方法,不让外界直接new
    private Single() {}
//  2、在类的内部,创建好对象
    //static :静态只能调用静态
    static private  Single s = new Single();
//  3、对外界提供一个公共的get(),返回一个已经准备好的对象
//static是为了外界不通过对象访问而是通过类名直接方法 
    static public Single get(){
       //注意:静态只能调用静态
       return s;
    }
}
懒汉式

默认不会实例化,什么时候用什么时候new。

class Single{
//  1、私有化构造方法,不让外界直接new
    private Single() {}
//  2、在类的内部,创建好对象
    //static :静态只能调用静态
    static private  Single s = null;
//  3、对外界提供一个公共的get(),返回一个已经准备好的对象
//static是为了外界不通过对象访问而是通过类名直接方法 
synchronized  static public Single get(){
       //注意:静态只能调用静态
       if(s==null){
           s = new Single();//会有安全问题
		}
       return s;
    }
}
安全帽与口罩检测数据集 一、基础信息 数据集名称:安全帽与口罩检测数据集 图片数量: - 训练集:1690张图片 - 验证集:212张图片 - 测试集:211张图片 - 总计:2113张实际场景图片 分类类别: - HelmetHelmet:戴安全帽的人员,用于安全防护场景的检测。 - personwithmask:戴口罩的人员,适用于公共卫生监测。 - personwith_outmask:未戴口罩的人员,用于识别未遵守口罩佩戴规定的情况。 标注格式:YOLO格式,包含边界框和类别标签,适用于目标检测任务。 数据格式:JPEG/PNG图片,来源于实际监控和场景采集,细节清晰。 二、适用场景 工业安全监控系统开发: 数据集支持目标检测任务,帮助构建自动检测人员是否佩戴安全帽的AI模型,适用于建筑工地、工厂等环境,提升安全管理效率。 公共卫生管理应用: 集成至公共场所监控系统,实时监测口罩佩戴情况,为疫情防控提供自动化支持,辅助合规检查。 智能安防与合规检查: 用于企业和机构的自动化安全审计,减少人工干预,提高检查准确性和响应速度。 学术研究与AI创新: 支持计算机视觉目标检测领域的研究,适用于安全与健康相关的AI模型开发和论文发表。 三、数据集优势 精准标注与实用性: 每张图片均经过标注,边界框定位准确,类别定义清晰,确保模型训练的高效性和可靠性。 场景多样性与覆盖性: 包含安全帽和口罩相关类别,覆盖工业、公共场所以及多种实际环境,样本丰富,提升模型的泛化能力和适应性。 任务适配性强: 标注兼容主流深度学习框架(如YOLO),可直接用于目标检测任务,便于快速集成和部署。 实际应用价值突出: 专注于工业安全和公共健康领域,为自动化监控、合规管理以及疫情防护提供可靠数据支撑,具有较高的社会和经济价值。
内容概要:本文围绕FOC电机控制代码实现与调试技巧在计算机竞赛中的应用,系统阐述了从基础理论到多场景优化的完整技术链条。文章深入解析了磁链观测器、前馈控制、代码可移植性等关键概念,并结合FreeRTOS多任务调度、滑动窗口滤波、数据校验与热仿真等核心技巧,展示了高实时性与稳定性的电机控制系统设计方法。通过服务机器人、工业机械臂、新能源赛车等典型应用场景,论证了FOC在复杂系统协同中的关键技术价值。配套的千行级代码案例聚焦分层架构与任务同步机制,强化工程实践能力。最后展望数字孪生、低代码平台与边缘AI等未来趋势,体现技术前瞻性。; 适合人群:具备嵌入式开发基础、熟悉C语言与实时操作系统(如FreeRTOS)的高校学生或参赛开发者,尤其适合参与智能车、机器人等综合性竞赛的研发人员(经验1-3年为佳)。; 使用场景及目标:① 掌握FOC在多任务环境下的实时控制实现;② 学习抗干扰滤波、无传感器控制、跨平台调试等竞赛实用技术;③ 提升复杂机电系统的问题分析与优化能力; 阅读建议:此资源强调实战导向,建议结合STM32等开发平台边学边练,重点关注任务优先级设置、滤波算法性能权衡与观测器稳定性优化,并利用Tracealyzer等工具进行可视化调试,深入理解代码与系统动态行为的关系。
【场景削减】拉丁超立方抽样方法场景削减(Matlab代码实现)内容概要:本文介绍了基于拉丁超立方抽样(Latin Hypercube Sampling, LHS)方法的场景削减技术,并提供了相应的Matlab代码实现。该方法主要用于处理不确定性问题,特别是在电力系统、可再生能源等领域中,通过对大量可能场景进行高效抽样并削减冗余场景,从而降低计算复杂度,提高优化调度等分析工作的效率。文中强调了拉丁超立方抽样在保持样本代表性的同时提升抽样精度的优势,并结合实际科研背景阐述了其应用场景与价值。此外,文档还附带多个相关科研方向的Matlab仿真案例和资源下载链接,涵盖风电、光伏、电动汽车、微电网优化等多个领域,突出其实用性和可复现性。; 适合人群:具备一定Matlab编程基础,从事电力系统、可再生能源、优化调度等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于含高比例可再生能源的电力系统不确定性建模;②用于风电、光伏出力等随机变量的场景生成与削减;③支撑优化调度、风险评估、低碳运行等研究中的数据预处理环节;④帮助科研人员快速实现LHS抽样与场景削减算法,提升仿真效率与模型准确性。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,理解拉丁超立方抽样的原理与实现步骤,并参考附带的其他科研案例拓展应用思路;同时注意区分场景生成与场景削减两个阶段,确保在实际项目中正确应用该方法。
道路坑洞目标检测数据集 一、基础信息 • 数据集名称:道路坑洞目标检测数据集 • 图片数量: 训练集:708张图片 验证集:158张图片 总计:866张图片 • 训练集:708张图片 • 验证集:158张图片 • 总计:866张图片 • 分类类别: CirEllPothole CrackPothole IrrPothole • CirEllPothole • CrackPothole • IrrPothole • 标注格式:YOLO格式,包含边界框和类别标签,适用于目标检测任务。 • 数据格式:图片为常见格式(如JPEG/PNG),来源于相关数据采集。 二、适用场景 • 智能交通监控系统开发:用于自动检测道路坑洞,实现实时预警和维护响应,提升道路安全。 • 自动驾驶与辅助驾驶系统:帮助车辆识别道路缺陷,避免潜在事故,增强行驶稳定性。 • 城市基础设施管理:用于道路状况评估和定期检查,优化维护资源分配和规划。 • 学术研究与创新:支持计算机视觉在公共安全和交通领域的应用,推动算法优化和模型开发。 三、数据集优势 • 精准标注与类别覆盖:标注高质量,包含三种常见坑洞类型(CirEllPothole、CrackPothole、IrrPothole),覆盖不同形态道路缺陷。 • 数据多样性:数据集涵盖多种场景,提升模型在复杂环境下的泛化能力和鲁棒性。 • 任务适配性强:标注兼容主流深度学习框架(如YOLO),可直接用于目标检测任务,支持快速模型迭代。 • 实际应用价值:专注于道路安全与维护,为智能交通和城市管理提供可靠数据支撑,促进效率提升。
废物分类实例分割数据集 一、基础信息 数据集名称:废物分类实例分割数据集 图片数量: - 训练集:2,658张图片 - 验证集:316张图片 - 测试集:105张图片 - 总计:2,974张图片(训练集 + 验证集) 分类类别: - 电子产品(electronics) - 玻璃瓶(gbottle) - 口罩(mask) - 金属(metal) - 塑料袋(pbag) - 塑料瓶(pbottle) - 废物(waste) 标注格式:YOLO格式,包含多边形点坐标,适用于实例分割任务。 数据格式:JPEG图片,来源于实际场景,涵盖多种废物物品。 二、适用场景 智能废物分类系统开发: 数据集支持实例分割任务,帮助构建能够自动识别和分割废物物品的AI模型,辅助垃圾分类和回收管理。 环境监测与环保应用: 集成至智能垃圾桶或监控系统,提供实时废物识别功能,促进环保和资源回收。 学术研究与技术创新: 支持计算机视觉与环境保护交叉领域的研究,助力开发高效的废物处理AI解决方案。 教育与培训: 数据集可用于高校或培训机构,作为学习实例分割技术和AI在环境应用中实践的重要资源。 三、数据集优势 类别多样性与覆盖广: 包含7个常见废物和可回收物品类别,如电子产品、玻璃瓶、口罩、金属、塑料袋、塑料瓶和废物,涵盖日常生活中的多种物品,提升模型的泛化能力。 精准标注与高质量: 每张图片均使用YOLO格式进行多边形点标注,确保分割边界精确,适用于实例分割任务。 任务导向性强: 标注兼容主流深度学习框架,可直接用于实例分割模型的训练和评估。 实用价值突出: 专注于废物分类和回收管理,为智能环保系统提供关键数据支撑,推动可持续发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值