Day 12 (抽象类与接口)
一、抽象类
1、abstract修饰类,即抽象类
- 此类不能实例化;
- 此类有构造器,子类实例化过程中会调用该父类的构造器;
2、abstract修饰方法,即抽象方法
- 只有方法的声明,没有方法体;
//抽象方法:eat()方法public abstract void eat();
- 包含抽象方法的类一定是抽象类(此方法不能被调,即该类不能不能实例化);
- 若子类重写了父类(父类为抽象类)中所有抽象方法后,才可以实例化,若没有重写,则子类也是一个抽象类;
3、利用抽象父类创建匿名子类或创建匿名子类的匿名对象
public class AbstractTest {public static void main(String[] args) {//1、利用抽象父类来创建匿名子类 但是有对象名 即f(并重写抽象父类中的抽象方法)Father f = new Father() {@Overridepublic void eat() {System.out.println("匿名子类重写的方法1");}@Overridepublic void play() {System.out.println("匿名子类重写的方法2");}};//2、匿名子类的匿名对象 (利用抽象父类声明匿名子类 且没有对象名)method(new Father() {@Overridepublic void eat() {System.out.println("");}@Overridepublic void play() {}});method(f);}//声明static方法 即在主类中可以直接调用 不用声明对象来调用public static void method(Father f){f.eat();f.play();}
}//抽象类(不能被实例化)
abstract class Father{String name;int age;public Father(){}public Father(String name,int age){this.name = name;this.age = age;}//抽象方法public abstract void eat();public abstract void play();
}class son extends Father{//如果不是抽象子类则必须重写父类中的抽象方法@Overridepublic void eat(){System.out.println("overwrite method : eat()");}@Overridepublic void play() {System.out.println("overwrite method : play()");}
}
4、模板方法设计模式
public class TemplateTest {public static void main(String[] args) {//多态创建实例Template t = new subTempalte();//调用子类继承的spendTime()方法t.spendTime();}
}abstract class Template{public void spendTime(){long start = System.currentTimeMillis();code();long end = System.currentTimeMillis();code();System.out.println("花费的时间为: " + (end-start));}public abstract void code();
}class subTempalte extends Template{@Override
//计算100以内质数的时间public void code() {for (int i = 2; i <= 100; i++){boolean isFlag = true;for (int j = 2; j <= Math.sqrt(i); j++){if (i % j == 0){isFlag = false;break;}}if (isFlag){System.out.println(i);}}}
}
二、接口
1、接口用interface声明
2、接口与类是并列的
3、JDK8之前的使用:可以定义全局常量和抽象方法
- 全局常量: 使用public static final定义,在接口中可以省略不写;
- 抽象方法: 使用public abstract定义,可以省略不写;
4、接口中不能定义构造器,则接口不可以实例化;
5、接口通过让类实现的方式来使用
- 如果实现类覆盖了接口中所有的抽象方法,则该实现类可以实例化;
- 如果实现类没有覆盖了接口中所有的抽象方法,则该实现类还是一个抽象类,即不能实例化;
6、Java可以实现多个接口(多重接口)---类是单继承的(不能多重继承但可以多层继承)
语句(先继承后实现):class A extends B implements C,D,E{ }
7、接口之间可以继承,多继承也可以
public class InterfaceTest {public static void main(String[] args) {//可以直接调用接口的静态属性System.out.println(Flyable.MAX_SPEED);System.out.println(Flyable.MIN_SPEED);//实现类覆盖接口中抽象方法后 可以实例化Plane plane = new Plane();plane.stop();}
}
interface Attackable{void attack();
}
interface Flyable{//全局常量的定义public static final int MAX_SPEED = 1000;int MIN_SPEED = 1; //省略了public static final//抽象方法的定义public abstract void fly();void stop(); //省略了public abstract
}
//实现类
class Plane implements Flyable{@Overridepublic void fly() {System.out.println("flying");}@Overridepublic void stop() {System.out.println("stop");}
}
//实现多接口 覆写了接口的所有抽象方法 可以实例化
class Bullet extends Object implements Flyable,Attackable{@Overridepublic void attack() {}@Overridepublic void fly() {}@Overridepublic void stop() {}
}
8、 JDK8的使用:可以定义全局常量、抽象方法、静态方法和默认方法
静态方法:static修饰,只能由接口调用(实现类不能使用)
默认方法:
- default修饰(实现类的对象可以调用,接口不能调用,非静态);
- 如果实现类中重写了接口中的方法,则调用的是重写的方法;
- 如果子类(实现类)继承的父类与实现的接口存在同名同参的默认方法,且子类(实现类)没有重写此方法,则调用时优先调用父类的该方法(若子类重写了该方法,则调用的是子类重写的方法);
- 如果实现类实现了多个接口(无继承),且多个接口中存在同名同参的默认方法,若子类没有重写该方法,则会出现接口冲突的错误,实现类必须重写该默认方法;
- 在子类(实现类)的方法中调用父类、接口中的被重写的方法;
//子类(实现类)的定义
class subCompare extends superCompare implements Compare{//重写接口中的默认方法 去掉了defaultpublic void compare3(){System.out.println("实现类中重写的compare2()方法");}public void myMethod(){//调用自己的重写的compare3方法compare3();//调用父类的compare3方法super.compare3();//调用接口的compare3方法Compare.super.compare3();}
}
三、内部类
JAVA允许一个类A声明在另一个类B中,类A称为内部类,类B为外部类;分为成员内部类(静态、非静态)和局部内部类(方法、构造器、代码块中)
class A{//非静态成员内部类class B{}//静态成员内部类static class C{}//代码块中声明局部内部类{class D{}}//构造器中声明局部内部类public A(){class E{}}//方法中声明局部内部类public void method(){class F{}}
}
成员内部类:
1、作为一个类:可以定义属性、方法和构造器等;可以用final修饰,既不能继承,若没有final则可以继承;可以用abstract修饰,
2、作为外部类的成员:可以调用外部类的结构;可以被static修饰;可以被四种不同权限修饰;
局部内部类:
1、在局部内部类的方法中,如果要调用局部内部类所声明的方法中的局部变量,则必须将该变量加final修饰(即常量);
//局部内部类:在方法中声明类public void method(){int num = 10; //final可以省略class G{public void show(){System.out.println(num); //10}}}
内部类实例的创建:
//创建静态成员内部类的对象A.C c = new A.C();//创建非静态成员类的对象A a = new A();A.B b = a.new B();
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
