Notas de estudio de entrada de Java (9) - clase abstracta, interfaz, clase de enumeración Enum, genérico, comodín de límite superior, comodín de límite inferior, comodín <?>

Una, clase abstracta

En una clase abstracta, si solo hay métodos abstractos y nada más, es mejor usar interfaces

Nota:

  1. La clase abstracta debe ser pública o protegida, el valor predeterminado es público.
  2. Su subclase debe implementar todos sus métodos abstractos; de lo contrario, la subclase también es una clase abstracta

2. Interfaz

Una clase tiene solo una clase principal, pero una interfaz puede tener varias interfaces principales.

Nota:

  1. Los miembros de datos de la interfaz son todos del tipo público estático De forma predeterminada, el sistema procesa el tipo público estático de forma predeterminada;
  2. Definición de interfaz, solo es necesario declarar, no es necesario darse cuenta;
  3. No se puede crear una instancia de la interfaz;
  4. De manera similar, el nombre del archivo de la interfaz debe ser el mismo que el nombre de la interfaz.

Cuando hay varios nombres de interfaces en la lista de interfaces, los nombres de las interfaces pueden separarse con comas.

Si solo desea implementar algunos de los métodos en la interfaz, primero puede definir una clase abstracta para implementar estos métodos en una clase abstracta (es posible que el cuerpo del método no se implemente), y la clase derivada de esta clase solo puede implementar individualmente métodos en lugar de implementar otros métodos.

Tres, clase de enumeración

1. Defina el tipo de enumeración

package PackageB;

// 定义枚举类型
enum LightColor{
    
    ,绿,}

class TrafficLight1 {
    
    
	// 声明枚举变量
	LightColor lightState;
	public TrafficLight1()
	{
    
    
		// 枚举常量的初始化,为红色
		this.lightState=LightColor.;
	}
	@Override
	public String toString()
	{
    
    
		// 得到枚举常量的名称
		return "当前灯的颜色:"+lightState.name();
	}
	// 改变灯的状态
	public void change()
	{
    
    
		// 返回枚举常量的序数
		int order=lightState.ordinal();
		// 得到所有的枚举常量
		LightColor lightColors[]=LightColor.values();
		order=(order+1)%lightColors.length;
		lightState=lightColors[order];
	}
	public static void  main(String[] args)
	{
    
    
		TrafficLight1 light=new TrafficLight1();
		for(int i=0;i<10;++i)
		{
    
    
			light.change();
		}
		if(light.lightState.equals(LightColor.))
		{
    
    
			System.out.println("现在的颜色:黄");
		}
		else if(light.lightState.equals(LightColor.绿))
		{
    
    
			System.out.println("现在的颜色:绿");
		}
		System.out.println(light);
	}
}

2. Tipo de enumeración personalizada

Nota:

  1. El constructor de un tipo de enumeración personalizado, modificado por privado
  2. Para los tipos de enumeración personalizados, primero defina varias constantes de enumeración, separadas por comas, y use un punto y coma para la última constante de enumeración
  3. La parte del parámetro real entre paréntesis después de cada constante de enumeración es coherente con el tipo de lista de parámetros del método de construcción del tipo de enumeración personalizado.

Definición de tipos enumerados

Tenga en cuenta que debe definir por separado el archivo del tipo de enumeración.

package PackageB;

import java.util.Random;

enum FigureEnum
{
    
    
	TRIANGLE("三角形",0),
	RECTANGLE("矩形",1),
	CIRCLE("圆形",2);
	String description;
	int order;
	private FigureEnum(String description,int order)
	{
    
    
		this.description=description;
		this.order=order;
	}
	public void setOrder(int order)
	{
    
    
		this.order=order;
	}
	public void setDescription(String description)
	{
    
    
		this.description=description;
	}
	// 返回当前枚举常量的说明部分
	public String getDescription()
	{
    
    
		return description;
	}
	public int getOrder()
	{
    
    
		return order;
	}
	public String getDescription(int order)
	{
    
    
		for(FigureEnum f:FigureEnum.values())
		{
    
    
			if(f.getOrder()==order)
			{
    
    
				return f.getDescription();
			}
		}
		// 这一句是需要添加的,如果不添加,程序会有错误
		// 因为,要保证返回一个String的类型,上面的条件语句中,可能没有满足返回条件
		// 这时,需要添加null的返回值,来保证程序能正常运行
		return null;
	}
	@Override
	public String toString()
	{
    
    
		return name()+"("+description+","+order+")";
	}
	public static FigureEnum getRandomFigureEnum()
	{
    
    
		int order1;
		Random rand=new Random();
		order1=rand.nextInt(FigureEnum.values().length);
		FigureEnum fes[]=FigureEnum.values();
		return fes[order1];
	}
}

prueba

package PackageB;

class FigureEnumTest {
    
    
	public static void main(String[] args) {
    
    
		FigureEnum type;
		for (int i = 0; i < 10; ++i) {
    
    
			type=FigureEnum.getRandomFigureEnum();
			switch(type)
			{
    
    
			case TRIANGLE:
				System.out.println("三角形!");
				break;
			case RECTANGLE:
				System.out.println("长方形!");
				break;
			case CIRCLE:
				System.out.println("圆形!");
				break;
			}
		}
	}
}

Resultados de la prueba

Inserte la descripción de la imagen aquí

Cuatro, genérico

1. Definición de métodos genéricos

package try_a_package;

import java.util.Date;

class TestGenericFun {
    
    
	public static<T> void fun1(T t)
	{
    
    
		System.out.println("fun1:"+t);
	}
	public static <T> T fun2(T t)
	{
    
    
		System.out.println("fun2:"+t);
		return t;
	}
	public static void main(String[] args)
	{
    
    
		fun1("String");
		fun1(3.1415);
		fun1(new Date());
		String msg=fun2("abcdef");
		System.out.println(msg);
	}
}

2. Definición de clase genérica

package PackageB;

import java.util.Date;

class Generic1<T> {
    
    
	private T data;
	// 构造方法
	public Generic1(T data)
	{
    
    
		this.data=data;
	}
	// 返回数据
	public T getData()
	{
    
    
		return data;
	}
	@Override
	public String toString()
	{
    
    
		return "dataType:"+data.getClass().getName()+",value:"+data;
	}
	public static void main(String[] args)
	{
    
    
		Generic1<String> g1=new Generic1("张三");
		System.out.println(g1);
		Generic1<Integer> g2=new Generic1(18);
		System.out.println(g2);
		Generic1<Date> g3=new Generic1(new Date());
		System.out.println(g3);
	}
}

Inserte la descripción de la imagen aquí

3. Comodín

(1) Preparación de la clase

package try_a_package;

public class Bowl <E>{
    
    
	private E thing;
	public Bowl(E drink)
	{
    
    
		this.thing=drink;
	}
	public Bowl()
	{
    
    
		this.thing=null;
	}
	public E getThing()
	{
    
    
		return thing;
	}
	public void setThing(E thing)
	{
    
    
		this.thing=thing;
	}
	@Override
	public String toString()
	{
    
    
		if(thing!=null)
			return "我是一个碗,装了"+thing;
		else
			return "我是一个碗,但没有东西";
	}
}


package try_a_package;

public class Food {
    
    

}

package try_a_package;

public class Milk extends Drink{
    
    
	@Override
	public String toString()
	{
    
    
		return "牛奶"+"(属于"+super.toString()+")";
	}
}

package try_a_package;

public class Wine extends Drink{
    
    
	@Override
	public String toString()
	{
    
    
		return "酒"+ "(属于"+super.toString()+")";
	}
}

(2) comodín de límite superior

<? extiende T>
package try_a_package;

public class TestUpWildcards {
    
    
	public static void main(String[] args)
	{
    
    
		Bowl<Drink> bowl1=new Bowl<>(new Drink());
		System.out.println(bowl1);
		// 下面这句话,没有什么错误,我给的参考书上说,这个有错误。
		//Bowl<Drink> bowl2=new Bowl<>(new Milk());
		// 但我本机运行没有错误,居然得出了正确的结果,没有报错,没有警告。
		// 愣住!!!!!!!!!!!
		// 不知道为啥,作为一个疑惑放到这里,之后深入学习了解以后,再进行修改。
		// 如果有大佬发现哪里有问题,记得告诉我哈》
		Bowl<? extends Drink> bowl2=new Bowl<>(new Milk());
		System.out.println(bowl2);
		Bowl<? extends Drink> bowl3=new Bowl<>(new Drink());
		System.out.println(bowl3);
		bowl2=new Bowl();
		System.out.println(bowl2);
		Wine wine1=new Wine();
		// 那本书上说,下面这一句也有错误??????
		// 我人傻了。
		// 这不正确运行了吗?
		// 以后再看,留个念想,回头再学一遍泛型。
		// 尽信书,不如无书。。。。。。。。。
		//bowl2.setThing(wine1);
		// 好吧,是出错了,我当时因为上面的那个没有改,导致下面这句是出错的。
		
		//wine1=(Wine)bowl3.getThing();
		// 可能注释错位置了,是上面那句出错了
		// 抛出了一个异常:
		// Exception in thread "main" java.lang.ClassCastException: class try_a_package.Milk cannot be cast to class try_a_package.Wine (try_a_package.Milk and try_a_package.Wine are in module hello_world_try of loader 'app')
		//		at hello_world_try/try_a_package.TestUpWildcards.main(TestUpWildcards.java:27)
		
		
	}
}

(3) comodín de límite inferior

<? extiende T>
package try_a_package;

public class TestLowWildcards {
    
    
	public static void main(String[] args)
	{
    
    
		Bowl<? super Milk> bowl1=new Bowl<> (new Milk());
		// 原本是装牛奶的碗
		System.out.println(bowl1);
		Milk milk1=new Milk();
		bowl1.setThing(milk1);
		//milk1=bowl1.getThing();
		// 该句有错误
		System.out.println(milk1);
		// 可以改装饮料(上一级)
		bowl1=new Bowl<>(new Drink());
		System.out.println(bowl1);
		// 也可以改装酒(同级)
		bowl1=new Bowl<>(new Wine());
		System.out.println(bowl1);
		bowl1=new Bowl<>(new Food());
		// 这个没有定义确切的内容?
		System.out.println(bowl1);
	}
} 

(4) Comodín <?>

Puede referirse a cualquier clase,
no puede ser asignado por el método setXX, pero el valor del atributo se puede obtener llamando al método getXX de esta clase, pero su tipo de datos es CAP # 1, por lo que no puede ser referenciado directamente.
Solo después de convertirlo en el tipo de datos correspondiente, puede asignar valores a otras variables.

package try_a_package;

public class TestWildcards {
    
    
	public static void main(String[] args)
	{
    
    
		Bowl<?>bowl1=new Bowl<>(new Milk());
		System.out.println(bowl1);
		Milk milk1=(Milk) bowl1.getThing();
		System.out.println(milk1);
		Drink drink=(Drink)bowl1.getThing();
		System.out.println(drink);
		Object ob=bowl1.getThing();
		System.out.println(ob);
		milk1=new Milk();
		System.out.println(milk1);
	}
}

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_41563270/article/details/108894161
Recomendado
Clasificación