内部类、枚举、注解学习

This commit is contained in:
markilue 2022-09-22 19:12:10 +08:00
parent 39fc3ed9a8
commit 3efc52a16b
7 changed files with 708 additions and 0 deletions

View File

@ -0,0 +1,96 @@
package com.markilue.java_learning.annotationTest;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.annotationTest
* @Author: dingjiawen
* @CreateTime: 2022-09-22 18:58
* @Description:
* TODO 测试注解:
* 1)一个完整的注解有三个部分
* 1.注解的声明就如同类方法变量等一样需要先声明后使用
* 2.注解的使用用于注解在包方法属性构造局部变量等上面的10个位置中一个或多个位置
* 3.注解的读取有一段专门用来读取这些使用的注解然后根据注解信息作出相应的处理这段程序称为注解处理流程这也是注解区别与普通注释最大的不同
* 2)系统预定义的三个最基本的注解:
* 1@Override:
* 用于检测被修饰的方法为有效的重写方法如果不是则报编译错误!
* 只能标记在方法上
* 它会被编译器程序读取
* 2.@Deprecated:
* 用于表示被标记的数据已经过时不建议使用
* 可以用于修饰 属性方法构造局部变量参数
* 它会被编译器程序读取
* 3.@SuppressWarnings:
* 抑制编译警告
* 可以用于修饰类属性方法构造局部变量参数
* 它会被编译器程序读取
* @Version: 1.0
*/
public class AnnotationTest {
@SuppressWarnings({"unused","rawtypes", "unchecked"})
@Test
public void test(){
int i;
//可以发现:这里没有声明List<T>类型,仍然没有报错
List list = new ArrayList();
list.add("");
list.add(123);
list.add("");
Father f = new Son();
f.show();
f.methodOl();
}
}
class Father{
@Deprecated
public void show() {
}
public void methodOl() {
System.out.println("Father Method");
}
public void print1n(){
System.out.println("Father Method");
}
public int sum(int... nums){
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum;
}
}
class Son extends Father{
/* @Override
public void method01() {
System.out.println("Son Method");
}
@Override
public void println(){
System.out.println("Father Method");
}
@Override
public long sum(int[] nums){
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum;
}*/
}

View File

@ -0,0 +1,101 @@
package com.markilue.java_learning.enumTest;
import org.junit.Test;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.enumTest
* @Author: dingjiawen
* @CreateTime: 2022-09-22 18:43
* @Description:
* TODO 测试枚举类
* 1枚举类的要求和特点:
* 1.枚举类的常量对象列表必须在枚举类的首行因为是常量所以建议大写
* 2.如果常量对象列表后面没有其他代码那么可以省略否则不可以省略
* 3.编译器给枚举类默认提供的是private的无参构造如果枚举类需要的是无参构造就不需要声明写常量对象列表时也不用加参数
* 4.如果枚举类需要的是有参构造需要手动定义private的有参构造调用有参构造的方法就是在常量对象名后面加(实参列表)就可以
* 5.枚举类默认继承的是java.lang.Enum类因此不能再继承其他的类型
* 6.JDK1.5之后switch提供支持枚举类型case后面可以写枚举常量名
* 2)枚举类的常用方法:
* 1.toString(): 默认返回的是常量名对象名可以继续手动重写该方法
* 2.name():返回的是常量名对象名 很少使用
* 3.ordinal():返回常量的次序号默认从0开始
* 4.values():返回该枚举类的所有的常量对象返回类型是当前枚举的数组类型是一个静态方法
* 5.valueOf(String name)根据枚举常量对象名称获取枚举对象
* 3)枚举类也是类可以实现接口可以同时实现多个接口可以统一实现也可以用匿名内部类的形式单独给某个常量对象实现抽象方法
* @Version: 1.0
*/
public class enumTest {
//枚举类常用方法测试
@Test
public void test(){
Season[] values = Season.values();
System.out.println(Season.SPRING.equals(1) ); //false
System.out.println(values[1].ordinal()); //1
for (int i = 0; i < values.length; i++) {
switch(values[i]){
case SPRING:
System.out.println(values[i]+":春暖花开,万物复苏"); //SPRING:春暖花开万物复苏
break;
case SUMMER:
System.out.println(values[i]+":百花争艳,郁郁葱葱");
break;
case AUTUMN:
System.out.println(values[i]+":菊桂飘香,百树凋零");
break;
case WINTER:
System.out.println(values[i]+":梅花独开,大地一色");
break;
}
}
}
@Test
public void test1(){
Season[] values = Season.values();
System.out.println(Season.SPRING.equals(1) ); //false
System.out.println(values[1].ordinal()); //1
for (int i = 0; i < values.length; i++) {
switch(values[i]){
case SPRING:
System.out.println(values[i]+":春暖花开,万物复苏"); //SPRING:春暖花开万物复苏
break;
case SUMMER:
System.out.println(values[i]+":百花争艳,郁郁葱葱");
break;
case AUTUMN:
System.out.println(values[i]+":菊桂飘香,百树凋零");
break;
case WINTER:
System.out.println(values[i]+":梅花独开,大地一色");
break;
}
}
}
}
enum Season{
SPRING,SUMMER,AUTUMN,WINTER
}
//枚举类实现抽象方法测试
interface Windiness{
void wind();
}
enum Season1 implements Windiness{
SPRING,SUMMER(){
@Override
public void wind() {
System.out.println("刮台风");
}
},AUTUMN,WINTER;
@Override
public void wind() {
System.out.println("刮风");
}
}

View File

@ -0,0 +1,57 @@
package com.markilue.java_learning.innerclass;
import org.junit.Test;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.innerclass
* @Author: dingjiawen
* @CreateTime: 2022-09-22 17:12
* @Description:
* TODO 测试静态内部类:
* 1)和外部类一样它只是定义在外部类中的另一个完整的类结构
* 1.可以继承自己的想要继承的父类实现自己想要实现的父接口们和外部类的父类和父接口无关
* 2.可以在静态内部类中声明属性方法构造器等结构包括静态成员
* 3.可以使用abstract修饰因此它也可以被其他类继承
* 4.可以使用final修饰表示不能被继承
* 5.编译后有自己的独立的字节码文件只不过在内部类名前面冠以外部类名和$符号
* 2)和外部类不同的是它可以允许四种权限修饰符publicprotected缺省private
* 1.外部类只允许public或缺省的
* 3)只可以在静态内部类中使用外部类的静态成员哪怕是私有的
* 1.在静态内部类中不能使用外部类的非静态成员哦
* 4)在外部类的外面不需要通过外部类的对象就可以创建静态内部类的对象
*
* TODO
* 值得注意的是:其实严格的讲在James Gosling等人编著的The Java Language Specification静态内部类不是内部类而是类似于C++的嵌套类的概念
* 外部类仅仅是静态内部类的一种命名空间的限定名形式而已所以接口中的内部类通常都不叫内部类因为接口中的内部成员都是隐式是静态的例如Map.Entry
* @Version: 1.0
*/
public class StaticInnerClass {
@Test
public void test(){
Outer2.Inner in= new Outer2.Inner(); //4)
in.inMethod(); //非静态方法可以通过new了对象以后使用
Outer2.Inner.inTest(); //静态方法可以直接使用
}
}
class Outer2{
private static int a = 1;
private int b = 2;
protected static class Inner{
static int d = 4;//可以
void inMethod(){
System.out.println("out.a = " + a);
// System.out.println("out.b = " + b);//错误的 3)
}
static void inTest(){
System.out.println("out.a = " + a);
}
}
}

View File

@ -0,0 +1,114 @@
package com.markilue.java_learning.innerclass;
import org.junit.Test;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.innerclass
* @Author: dingjiawen
* @CreateTime: 2022-09-22 16:49
* @Description:
* TODO 测试非静态内部类:
* 1)和外部类一样它只是定义在外部类中的另一个完整的类结构
* 1.可以继承自己的想要继承的父类实现自己想要实现的父接口们和外部类的父类和父接口无关
* 2.可以在非静态内部类中声明属性方法构造器等结构但是**不允许声明静态成员**但是可以继承父类的静态成员而且可以声明静态常量
* 3.可以使用abstract修饰因此它也可以被其他类继承
* 4.可以使用final修饰表示不能被继承
* 5.编译后有自己的独立的字节码文件只不过在内部类名前面冠以外部类名和$符号
* 2)和外部类不同的是它可以允许四种权限修饰符publicprotected缺省private
* 1.外部类只允许public或缺省的
* 3)还可以在非静态内部类中使用外部类的所有成员哪怕是私有的
* 4)在外部类的静态成员中不可以使用非静态内部类哦
* 1.就如同静态方法中不能访问本类的非静态成员变量和非静态方法一样
* 5)在外部类的外面必须通过外部类的对象才能创建非静态内部类的对象
* 1.因此在非静态内部类的方法中有两个this对象一个是外部类的this对象一个是内部类的this对象
* @Version: 1.0
*/
public class UnStaticInnerClass {
@Test
public void test(){
Outer out = new Outer();
Outer.Inner in= out.new Inner(); //第五点5
in.inMethod();
Outer.Inner inner = out.getInner();
inner.inMethod();
}
}
class Father{
protected static int c = 3;
}
class Outer{
private static int a = 1;
private int b = 2;
protected class Inner extends Father{
// static int d = 4;//错误 1的第2点
int b = 5;
void inMethod(){
System.out.println("out.a = " + a); //3)
System.out.println("out.b = " + Outer.this.b);
System.out.println("in.b = " + b);
System.out.println("father.c = " + c);
}
}
public static void outMethod(){
// Inner in = new Inner();//错误的 //4)
}
public Inner getInner(){
return new Inner();
}
}
//简单面试题
class Test1{
public Test1(){
Inner s1 = new Inner();
s1.a = 10;
Inner s2 = new Inner();
s2.a = 20;
Test1.Inner s3 = new Test1.Inner();
System.out.println(s3.a);
}
class Inner{
public int a = 5;
}
public static void main(String[] args) {
Test1 t = new Test1();
Inner r = t.new Inner();
System.out.println(r.a); //5 5
}
}
//高难面试题
class TestInner{
public static void main(String[] args){
Outer1.Inner in = new Sub();
in.method();//输出 hello inner
}
}
class Outer1 {
abstract class Inner{
abstract void method();
}
}
class Sub extends Outer1.Inner{ //注意这里是Outer1.Inner
//不写这个构造方法,上面的Outer1.Inner会报错
static Outer1 out = new Outer1();
Sub(){
out.super();
}
@Override
void method() {
System.out.println("hello inner");
}
}

View File

@ -0,0 +1,61 @@
package com.markilue.java_learning.innerclass;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.innerclass
* @Author: dingjiawen
* @CreateTime: 2022-09-22 18:03
* @Description:
* TODO 测试局部内部类:
* 1)和外部类一样它只是定义在外部类的`某个方法`中的另一个完整的类结构
* 1.可以继承自己的想要继承的父类实现自己想要实现的父接口们和外部类的父类和父接口无关
* 2.可以在局部内部类中声明属性方法构造器等结构但不包括静态成员除非是从父类继承的或静态常量
* 3.可以使用abstract修饰因此它也可以被同一个方法的在它后面的其他内部类继承
* 4.可以使用final修饰表示不能被继承
* 5.编译后有自己的独立的字节码文件只不过在内部类名前面冠以外部类名$符号编号
* 这里有编号是因为同一个外部类中不同的方法中存在相同名称的局部内部类
* 2)和成员内部类不同的是它前面不能有权限修饰符等
* 3)局部内部类如同局部变量一样有作用域
* 4)局部内部类中使用能访问外部类的静态还是非静态的成员取决于所在的方法
* 5)局部内部类中还可以使用所在方法的局部常量即用final声明的局部变量
* 1.JDK1.8之后如果某个局部变量在局部内部类中被使用了自动加final
* 2.为什么一定要使用final? 因为如果c不是final的那么method方法执行完method的栈空间就释放了那么c也就消失了,如果方法返回值中包含这个类的这个值则无法取到
* @Version: 1.0
*/
public class partInnerClass {
}
class Outer3{
private static int a = 1;
private int b = 2;
public static void outMethod(){
final int c = 3; //5)
class Inner{ //2)
public void inMethod(){
System.out.println("out.a = " + a);
// System.out.println("out.b = " + b);//错误的因为outMethod是静态的 //4)
System.out.println("out.local.c = " + c);
}
}
Inner in = new Inner();
in.inMethod();
}
public void outTest(){
final int c = 3;
class Inner{ //5)
public void inMethod(){
System.out.println("out.a = " + a);
System.out.println("out.b = " + b);//可以因为outTest是飞静态的
System.out.println("method.c = " + c);
}
}
Inner in = new Inner();
in.inMethod();
}
}

View File

@ -0,0 +1,199 @@
package com.markilue.java_learning.interfaceTest;
import org.junit.Test;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.interfaceTest
* @Author: dingjiawen
* @CreateTime: 2022-09-22 15:28
* @Description:
* TODO 测试java中的接口
* 1那么接口的内部主要就是 封装了方法包含抽象方法JDK 7及以前默认方法和静态方法JDK 8私有方法JDK 9
* 2接口中有多个抽象方法时实现类必须重写所有抽象方法如果抽象方法有重名的只需要重写一次
* 3当一个类既继承一个父类又实现若干个接口时父类中的成员方法与接口中的抽象方法重名子类就近选择执行父类的成员方法参见ABCD
* 4)当一个类同时实现了多个接口而多个接口中包含方法签名相同的默认方法时,必须要作出选择(可以重写 也可以选择一个继承)参见EFGH
* 5一个接口能继承另一个或者多个接口接口的继承也使用 `extends` 关键字子接口继承父接口的方法
* 1.子接口重写默认方法时default关键字可以保留
* 2.子类重写默认方法时default关键字不可以保留
* 6接口中其他成员特点
* 1.接口中无法定义成员变量但是可以定义常量其值不可以改变默认使用public static final修饰
* 2.接口中没有构造方法不能创建对象
* 3.接口中没有静态代码块
* 7接口类型的变量与实现类的对象之间也可以构成多态引用通过接口类型的变量调用方法最终执行的是你new的实现类对象实现的方法体
* 8常用接口:java.lang.Comparablejava.util.Comparatorjava.lang.Cloneable
* 1.java.lang.Comparable实现这个接口的类需要实现compareTo(Object obj)方法 从而实现与另一个对象的比较;
* 如果当前比obj大则返回一个正整数等于返回0小于返回负整数
* 2.java.util.Comparator实现这个接口的类需要实现compare(Object o1,Object o2)方法 当我们修改不了源码,又希望这类对象能做比较的时候使用;
* 如果当前比obj大则返回一个正整数等于返回0小于返回负整数
* 3.java.lang.Cloneable实现这个接口的类需要实现clone()方法可以实现造一个和当前对象各种属性值一模一样的对象当然地址肯定不同
* @Version: 1.0
*/
public class InterfaceTest {
//测试第三点3
@Test
public void test(){
C c = new C();
c.methodA();
B b = new B();
b.methodA();
/*
打印结果:
DDDDDDDDDDDD
BBBBBBBBBBBB
*/
}
//测试第七点7
@Test
public void test1(){
A c = new C();
c.methodA();
A b = new B();
b.methodA();
/*
打印结果:
DDDDDDDDDDDD
BBBBBBBBBBBB
*/
}
//测试第八点8)
@Test
public void test2() throws CloneNotSupportedException {
Teacher src = new Teacher(1,"柴老师");
Object clone = src.clone();
System.out.println(clone);
System.out.println(src == clone);
System.out.println(src.equals(clone));
System.out.println(new Object().getClass());
System.out.println(clone.getClass());
/*
结果:
Teacher [id=1, name=柴老师]
false
true
class java.lang.Object
class com.markilue.java_learning.interfaceTest.Teacher
*/
}
}
interface A {
public default void methodA(){
System.out.println("AAAAAAAAAAAA");
}
}
class D {
public void methodA(){
System.out.println("DDDDDDDDDDDD");
}
}
class C extends D implements A {
// 未重写methodA方法
}
class B extends D implements A{
//当然也可以选择重写
public void methodA(){
System.out.println("BBBBBBBBBBBB");
}
}
interface E{
public default void d(){
System.out.println("今晚7点-8点陪我吃饭看电影");
}
}
interface F{
public default void d(){
System.out.println("今晚7点-8点陪我逛街吃饭");
}
}
//选择保留其中一个通过接口名.super.方法名"的方法选择保留哪个接口的默认方法。
class G implements E,F{
@Override
public void d() {
E.super.d();
}
}
//选择自己完全重写
class H implements E,F{
@Override
public void d() {
System.out.println("自己待着");
}
}
class Teacher implements Cloneable{
private int id;
private String name;
public Teacher(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Teacher() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + "]";
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}

View File

@ -0,0 +1,80 @@
package com.markilue.java_learning.interfaceTest;
import org.junit.Test;
/**
* @BelongsProject: java_learning
* @BelongsPackage: com.markilue.java_learning.interfaceTest
* @Author: dingjiawen
* @CreateTime: 2022-09-22 16:07
* @Description:
* TODO 接口常见面试题排错
* 1第一题参见ZXS类
* @Version: 1.0
*/
public class Problem {
}
interface Z{
int x=0;
}
class X{
int x=1;
}
class S extends X implements Z{
public void px(){
// System.out.println(x);
}
public static void main(String[] args) {
new S().px();
//这里直接报错了 com.markilue.java_learning.interfaceTest.X 中的变量 x com.markilue.java_learning.interfaceTest.Z 中的变量 x 都匹配
}
}
interface Playable{
void play();
}
interface Bounceable{
void play();
}
interface Rollable extends Playable,Bounceable{
Ball ball=new Ball("PingPang");
}
class Ball implements Rollable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Ball(String name) {
this.name = name;
}
public Ball() {
}
@Override
public void play() {
Ball football = new Ball("football");
System.out.println(ball.getName());
}
public static void main(String[] args) {
new Ball().play();//PingPang
}
}