一、接口
接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为。接口指明了一个类必须要做什么和不能做什么,相当于类的蓝图,是一种规范。
1.特点:
接口和类是两个并列的结构
接口不能实例化,当中没有构造器
接口具有多态性
2.为什么要使用接口
在Java中不支持多继承,可以通过接口来弥补这个局限。
3.使用:
使用interface来修饰
JDK7及以前,接口内只能定义全局常量和抽象方法(可以直接通过“接口名.属性来调用属性”)
JDK8以后,除此之外,还可以定义静态方法、默认方法。
java开发中,接口通过类去实现的方式来使用,如果实现类覆盖了接口中所有的抽象方法,则此实现类就可以实例化,否则该实现了仍为一个抽象类。
多继承的格式:
class AA extends BB implements CC,DD...{}
interface Flyable{
//全局常量
public static final int MAX_SPEED = 7900;
int MIN_SPEED = 1;//也可以省略
//抽象方法
public abstract void fly();
void stop();//省略修饰
}
interface Attackable{
void attck();
}
class Plane implements Flyable,Attackable{
@Override
public void fly() {
System.out.println("飞机起飞");
}
@Override
public void stop() {
System.out.println("飞机降落");
}
@Override
public void attck() {
System.out.println("飞机发射导弹");
}
}
4.接口具有多态性,是一种规范。
public class Main {
public static void main(String[] args) {
Computer com = new Computer();
Upan usb = new Upan();
com.transferDate(usb);
}
}
class Computer{
//这里体现了接口的多态性。
public void transferDate(USB usb){
usb.start();
System.out.println("具体工作细节 ");
usb.stop();
}
}
interface USB{
void start();
void stop();
}
class Upan implements USB{
@Override
public void start() {
System.out.println("U盘开始工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
接口的多态性:
//非匿名实现类的非匿名的对象
Upan usb = new Upan();
//非匿名实现类的匿名对象
com.transferDate(new Upan());
//匿名实现类的非匿名对象
USB phone = new USB() {
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void stop() {
System.out.println("手机停止工作");
}
};
//匿名实现类的匿名对象
com.transferDate(new USB() {
@Override
public void start() {
System.out.println("MP3开始工作");
}
@Override
public void stop() {
System.out.println("MP3停止工作");
}
});
5.改错题:
练习:
public class Main {
public static void main(String[] args) {
CompareableCircle c1 = new CompareableCircle(3.4);
CompareableCircle c2 = new CompareableCircle(3.2);
int compareValue = c1.compareTo(c2);
if(compareValue > 0){
System.out.println("c1对象大");
}else if(compareValue < 0){
System.out.println("c2对象大");
}else{
System.out.println("一样大");
}
}
}
interface CompareObject{
public abstract int compareTo(Object o);
}
class Circle{
private double redius;
public Circle(double redius) {
this.redius = redius;
}
public double getRedius() {
return redius;
}
}
class CompareableCircle extends Circle implements CompareObject{
public CompareableCircle(double redius) {
super(redius);
}
@Override
public int compareTo(Object o) {
if(o == this){
return 0;
}
if(o instanceof CompareableCircle){
CompareableCircle c = (CompareableCircle)o;
if(this.getRedius() > c.getRedius()) return 1;
else if(this.getRedius() > c.getRedius()) return -1;
else return 0;
}else{
throw new RuntimeException("传入的数据类型不匹配");
}
}
}
抽象类和接口的区别
- 抽象类可以有构造方法,接口中不能有构造方法。
- 抽象类中可以有普通成员变量,接口中没有普通成员变量
- 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
- 抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
- 抽象类中可以包含静态方法,接口中不能包含静态方法。
- 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
- 一个类可以实现多个接口,但只能继承一个抽象类。
二、内部类
1、概念
可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。 广泛意义上的内部类一般来说包括这四种:
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类
2、成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
class Outer {
private double x = 0;
public Outer(double x) {
this.x = x;
}
class Inner { //内部类
public void say() {
System.out.println("x="+x);
}
}
}
特点: 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。
如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
外部使用成员内部类
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
2、局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或
者该作用域内。
class Person{
public Person() {
}
}
class Man{
public Man(){
}
public People getPerson(){
class Student extends People{ //局部内部类
int age =0;
}
return new Student();
}
}
new 父类构造器(参数列表)|实现接口()
{
//匿名内部类的类体部分
}
在这里我们看到使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一
个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。当然这个引用是隐
- 使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
- 匿名内部类中是不能定义构造函数的。
- 匿名内部类中不能存在任何的静态成员变量和静态方法。
- 匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
- 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
- 只能访问final型的局部变量(因为内部类会被单独编译成一个字节码文件,保证这个文件中的变量与外面的变量决定一致不可更改)
4、静态内部类
public class Test {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
}
class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}
三、方法的可变参数
返回值类型 方法名称(数据类型…参数名称){
参数在方法内部 , 以数组的形式来接收
}