接口
定义
[修饰符] interface 接口名 extends 父接口1,父接口2...
{
零到多个常量定义...
零到多个抽象方法定义...
零到多个内部类、接口、枚举定义...
零到多个默认方法(默认权限为public,默认方法是需要在实现类中调用)或类方法(可以通过类调用,默认都是public)定义...
}
public interface example1 {
// 常量定义
int NUM = 50;
// 抽象方法定义
void out();
// 默认方法
default void test()
{
System.out.println("默认的test方法");
}
// 默认类方法
static String staticTest()
{
return "接口里的类方法";
}
}
public interface example2 {
int getProduceTime();
}
实现
[修饰符] class 类名 extends 父类 implements 接口1,接口2...
{
类体部分
}
必须实现接口里面定义的对应抽象方法才可以使用
Output o = new Printer();,需要定义out和getDate方法
或
Product p = new Printer();,需要定义getProduceTime方法
public class Printer implements example1, example2{
@Override
public void out()
{
...
}
@Override
public void getDate(String msg)
{
...
}
@Override
public int getProduceTime()
{
...
}
}
内部类
非静态内部类
一共有四种访问控制权限
public class Outclass
{
class{}
private class{}
protected class{}
public class{}
}
例子
public class Cow
{
private double weight;
// 定义一个非静态内部类
private class CowLeg
{
// 非静态内部类的两个实例变量
private double length;
private String color;
// 非静态内部类的两个重载的构造器
public CowLeg(){}
public CowLeg(double length , String color)
{
..
}
// 非静态内部类的实例方法
public void info()
{
System.out.println("当前牛腿颜色是:"
+ color + ", 高:" + length);
// 直接访问外部类的private修饰的成员变量
System.out.println("本牛腿所在奶牛重:" + weight);
}
}
}
静态内部类
一共有四种访问控制权限
public class Outclass
{
static class{}
private static class{}
protected static class{}
public static class{}
}
例子
public class StaticInnerClassTest
{
private int prop1 = 5;
private static int prop2 = 9;
static class StaticInnerClass
{
// 静态内部类里可以包含静态成员
private static int age;
public void accessOuterProp()
{
// 下面代码出现错误:
// 静态内部类无法访问外部类的实例变量
System.out.println(prop1);
// 下面代码正常
System.out.println(prop2);
}
}
}
Java 8改进的匿名内部类
语法格式
new 实现接口() | 父类构造器(实参列表)
{
// 匿名内部类的类体部分
}
示例1
当通过实现接口来创建内部类,匿名内部类不能显示创建构造器,所以它只有一个隐式的无参构造器。可以传入一个临时类,也可以进行封装后传入
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();
// 调用test()方法时,需要传入一个Product参数,
// 此处传入其匿名实现类的实例
ta.test(new Product()
{
public double getPrice()
{
return 567.8;
}
public String getName()
{
return "AGP显卡";
}
});
}
}
示例2
如果通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器
abstract class Device
{
private String name;
public abstract double getPrice();
public Device(){}
public Device(String name)
{
this.name = name;
}
// 此处省略了name的setter和getter方法
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}
public class AnonymousInner
{
public void test(Device d)
{
System.out.println("购买了一个" + d.getName()
+ ",花掉了" + d.getPrice());
}
public static void main(String[] args)
{
AnonymousInner ai = new AnonymousInner();
// 调用有参数的构造器创建Device匿名实现类的对象
ai.test(new Device("电子示波器")
{
public double getPrice()
{
return 67.8;
}
});
// 调用无参数的构造器创建Device匿名实现类的对象
Device d = new Device()
{
// 初始化块
{
System.out.println("匿名内部类的初始化块...");
}
// 实现抽象方法
public double getPrice()
{
return 56.2;
}
// 重写父类的实例方法
public String getName()
{
return "键盘";
}
};
ai.test(d);
}
}
Java 8 新增的Lambda表达式
无参数
interface Eatable
{
void taste();
}
// 调用该方法需要Eatable对象
public void eat(Eatable e)
{
System.out.println(e);
e.taste();
}
class.eat(()-> System.out.println("苹果的味道不错!"));
有一个参数
interface Flyable
{
void fly(String weather);
}
// 调用该方法需要Flyable对象
public void drive(Flyable f)
{
System.out.println("我正在驾驶:" + f);
f.fly("【碧空如洗的晴日】");
}
// 调用
class.drive(weather ->
{
System.out.println("今天天气是:" + weather);
System.out.println("直升机飞行平稳");
});
#
interface Addable
{
int add(int a , int b);
}
// 调用该方法需要Addable对象
public void test(Addable add)
{
System.out.println("5与3的和为:" + add.add(5, 3));
}
// Lambda表达式的代码块只有一条语句,省略花括号
// 代码块中只有一条语句,即使该表达式需要返回值,也可以省略return关键字。
lq.test((a , b)->a + b);