JAVA基础-接口、内部类、枚举

一、接口

1.什么是接口

前面我们已经学习了抽象类(被abstract修饰的类)以及抽象方法,如果在一个类中所有的方法都是抽象方法,那么我们就可以把这个类定义为接口。

2.接口的定义

使用关键字interface来定义。

public interface Animal{
    public abstract void eat();
    public abstract void sleep();
}

从上述代码中我们可以看出,在接口中的所有方法都是抽象方法,而抽象方法存在的意义就是为了让子类重写这个方法。

3.接口的实现(I)

抽象类的子类(实现类)使用implements来实现接口

public class People implements Animal{
    public abstract void eat(){
        
        System.out.println("人吃饭");
    }
    public abstract void sleep(){
    
        System.out.println("人睡觉");
    }
}
}

4.接口成员分析

先上案例:

interface Animal {
public static final String NAME = "xxx";
    void eat();
    abstract void sleep();
    public void breathing();
    public default void test(){
        System.out.println("接口中的实例方法");
    }
    public static void test1(){
        System.out.println("接口中的静态方法");
    }
}

总结:

1.接口中所有的成员变量都常量(被public static final 修饰);

2.接口中的抽象方法都是公共,都会被public abstract来修饰,接口中可以有实例方法和静态方法,实例方法需要使用default修饰;

3.接口中是没构造器的;

原因:其一是接口中所有的方法都抽象方法,而构造器是用来创建类的实例的;其二abstract关键字是不能修饰构造器的,所以接口中不能有构造器(构造方法);

4… 接口不能直接实例化,需要子类通过implements关键字来实现;

5.接口的实现(II)

public interface Animal{
    public abstract void eat();
    public abstract void sleep();
}

public interface People{
 	public abstract void sing();
    public abstract void dance();
}

public Man implements People,Animal{
     public abstract void eat(){
         System.out.println("男人吃饭");
     }
    public abstract void sleep(){
        System.out.println("男人睡觉");
    }
    public abstract void sing(){
        System.out.println("男人唱歌");
    }
    public abstract void dance(){
        System.out.println("男人跳舞");
    }
}

从上述代码中可以得出:接口的实现是可以多实现的。

6.接口与抽象类的对比

抽象类

接口

定义

使用abstract关键字定义

使用interface关键字定义

成员

构造方法、抽象方法、普通方法、常量、变量

常量、抽象方法、默认方法、静态方法

使用

继承(extends)

实现(implements)

关系

子类只能继承一个抽象类

子类(实现类)可以实现多个接口,接口与接口之间只能使用继承

实例

new

接口不能直接实例化

二、内部类

1.什么是内部类

在Java类内部定义的类,就是内部类。

如:

public class A{
    class B{  
    }
}

这里我没呢就可以称B是A的内部类,相对而言A就是B的外部类。

对于内部类而言,根据其在外部类中的位置可以将内部类分为:成员内部类、局部内部类、匿名内部类

根据内部类的修饰符也可以将内部类分为:静态内部类和非静态内部类

2.成员内部类

定义:如果一个类中另一个类的中,那么就叫成员内部类

public class Outer{
    int num = 10;
    public void show(){
        Sysout.out.println("外部内show方法")
    }
   public class Inner{  
        int age = 18;
        System.out.println(num);
       	show();
       
    }
}
public class InnerClassDemo{
public static void main(String[] args) {
// 对于非静态成员内部类,实例的格式如下:
// new 外部对象.new 内部对象
	Outer.Inner oi = new Outer().new Inner();
		oi.show();	
}
}

总结:

  • 对于非静态成员内部类而言,要想实例化内部类,需要使用的格式为:外部类名.内部类名 = 外部类对象.内部 类对象
  • 内部类中可以获取外部类的属性和方法。
  • 内部类使用外部类的属性和方法就好像是内部类自己的属性和方法一样。
  • 外部类想使用内部类的属性和方法需要创建内部类的对象后才可以。

3.局部内部类

定义:如果一个类中另一个类的方法中,那么就叫局部内部类。

示例:

public class Outer {
    
  public void build() {
    
	public class Inner { // 局部内部类
	  public void print() {
    
		System.out.println("内部类打印。");
		}
	}
// 要想使用局部内部类需要在方法中创建内部对象
        Inner inner = new Inner();
        inner.print();
  }
}
// 局部内部类
public class InnerClassDemo0 {
  public static void main(String[] args) {
            Outer outer = new Outer();
            outer.build();
	}
}

总结:局部内部类需要在外部类的方法中创建去创建实例。

4.匿名内部类

定义:一个内部类没有名字那么这个内部类就是一个匿名内部类。

示例1:

public interface InterA {
    
	public abstract void fun1();
}

// 匿名内部类
public class InnerClassDemo{   
  public void callInner(InterA interA) {   
    	interA.fun();
	}
    
	public static void main(String[] args) {
    
		InnerClassDemo icd = new InnerClassDemo();
    
		icd.callInner(new InterA() { // 匿名内部类

 			public void fun() {
				System.out.println("匿名方法实现");
			}
		}); 
	}
}

示例2:

interface Product {
	public double getPrice();
	public String getName();
}
public class AnonymousTest {
	public void test(Product p) {
		System.out.println(p.getName() + p.getPrice());
	}
	public static void main(String[] args) {
		AnonymousTest ta = new AnonymousTest();
		ta.test(new Product() {
			public double getPrice() {
				return 567.8;
			}
			public String getName() {
				return "AGP显卡";
			}
		});
	}
}

实例3:

abstract class Human {
	public abstract void spreak();
}
public class InnerClassDemo05 {
	public static void main(String[] args) {
		Human human = new Human() {// 不是匿名,因为有一个human的引用。
			@Override
			public void spreak() {
				System.out.println("我是一个中国人。");
			}
	};
	human.spreak();
// 匿名:
new Human() {
	public void spreak() {
				System.out.println("我是一个外国人。");
			}
		}.spreak();
	}
}

示例4:

abstract class Human {
    public abstract void spreak();
    public abstract void sing();
}
public class InnerClassDemo {
    public static void main(String[] args) {
        Human human = new Human() {// 不是匿名,因为有一个human的引用。
            public void spreak() {
                System.out.println("我是一个中国人。");
            }
            public void sing() {
                System.out.println("我会唱中文歌。");
            }
        };
        human.spreak();
        human.sing();
        // 匿名:
        new Human() {
            public void spreak() {
                System.out.println("我是一个外国人。");
            }
            public void sing() {
                System.out.println("我会唱英文歌。");
            }
        }.sing(); // 匿名的方式只能调用一个方法
    }
}

三、枚举

1.枚举的定义

示例:

//语法
public enum 枚举类名{
    枚举值1,枚举值2,….枚举值n
}

public enum SeasonEnum {
    SPRING,SUMMER,AUTUMN,WINTER;
}
public class EnumDemo02 {
    public static void main(String[] args) {
        SeasonEnum spring = SeasonEnum.SPRING;
        System.out.println(spring);
    }
}

2.枚举总结:

1.枚举和普通的Java类是同级别的,普通的类使用class来定义,而枚举使用enum来定义。

2.每一个枚举类都是抽象类Enum的子类。

3.枚举类中每一个元素都是枚举类的对象或者叫实例对象;

4.枚举类中的元素需要定义在第一行,多个之间用逗号分隔,最后的分号可以有也可以没有;

5.枚举类的构造方法是私有化的(private);