抽象类和抽象类方法、接口、内部类

  • 1、抽象类和抽象方法(abstract关键字)
  • 2、接口
  • 3、内部类

1、抽象类和抽象方法(abstract关键字)


1、abstract 抽象的
2、abstract可以用来修饰的结构:类、方法

3、abstract 修饰类:抽象类

  • 此类不能实例化,抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
  • 抽象类中一定有构造器,便于子类实例化的时候调用(涉及:子类对象实例化的过程)
  • 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作。

4、abstract修饰方法:抽象方法

  • 抽象方法只有方法的声明,没有方法体。
  • 包含抽象方法的类一定是抽象类,反之,抽象类中是可以有普通的方法。
  • 若子类重写了父类的所有的抽象方法后,此子类方可实例化,若子类没有重写父类的所有抽象方法,此子类也一定是个抽象类,需要使用abstract关键字。(直接父类和间接父类都算)
public class AbstractTest {public static void main(String[] args) {//        Person p1 = new Person();//抽象类不能实例化
//        p1.eat();}
}
abstract class Creature{public abstract void breath();//抽象方法,只有方法的声明,没有方法的实现
}abstract class Person extends Creature{//继承了Creature但是没有实现父类的抽象方法,Person也为抽象类String name;int age;abstract public void eat();public void run(){System.out.println("跑得贼快!");}
}class Student extends Person {//Student继承了Person,Person继承了Creature@Overridepublic void eat() {System.out.println("吃好的!");}@Overridepublic void breath() {System.out.println("呼吸新鲜空气!");}
}

abstract 使用上的注意点:
1、abstract 不能用来修饰属性、构造器等结构。
2、abstract不能用来修饰私有方法、静态方法、final的方法、final的类。

思考题:
问题1:为什么抽象类不可以使用final关键字声明?
问题2:一个抽象类中可以定义构造器吗?
问题3:是否可以这样理解:抽象类就是比普通类多定义了抽象方法,除了不能直接进行类的实例化操作之外,并没有任何的不同?

练习:
编写一个Employee类,声明为抽象类,
包含如下三个属性:name,id,salary。
提供必要的构造器和抽象方法:work()。
对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。
请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问。

//Manager类
public class Manager extends Employee{private double bonus;//奖金public Manager(String name, int id, double salary, double bonus) {super(name, id, salary);this.bonus = bonus;}@Overridepublic void work() {System.out.println("管理员工,提高哦公司运行效率!");}
}
//CommonEmployee类
public class CommonEmployee extends Employee {@Overridepublic void work() {System.out.println("员工在一线车间生产产品");}
}
//测试类
public class EmployeeTest {public static void main(String[] args) {Employee manager = new Manager("库克",1001,5000,50000);manager.work();CommonEmployee commonEmployee = new CommonEmployee();commonEmployee.work();}
}

管理员工,提高哦公司运行效率!
员工在一线车间生产产品

抽象匿名子类:自能用一次
作用:图个方便,只能用一次

public class PersonTest {public static void main(String[] args) {Worker worker = new Worker();method1(worker);//非匿名的类非匿名对象method(new Student());//匿名对象,对象没有名字,对象有(非匿名的类,非匿名的对象)System.out.println("--------------------");//*******创建了一个匿名类的对象p,需要做的就是将方法重写*****Person p = new Person() {//这个Person是Person的子类,用Person的名字作为充当@Overridepublic void eat() {System.out.println("干饭");}@Overridepublic void breath() {System.out.println("我感觉不到呼吸");}};method1(p);System.out.println("----------------");//*****创建匿名子类的匿名对象*****method1(new Person() {@Overridepublic void eat() {System.out.println("干饭干饭!!!");}@Overridepublic void breath() {System.out.println("呼吸都是错的!");}});}public static void method1(Person p){p.eat();p.breath();}public static void method(Student p){}
}class Worker extends Person{@Overridepublic void breath() {}@Overridepublic void eat() {}
}

干饭
我感觉不到呼吸


干饭干饭!!!
呼吸都是错的!

模板方法的设计模式
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

例1

/*
抽象类的应用:模板方法的设计模式*/public class TemplateTest {public static void main(String[] args) {SubTemplate t = new SubTemplate();t.spendTime();}
}//计算某段代码执行所需要花费的时间
abstract class Template{public void spendTime(){long start = System.currentTimeMillis();//1970年到现在的毫秒数code();//不确定的部分(易变的部分)long end = System.currentTimeMillis();System.out.println("花费的时间为:"+(end - start));}public abstract void code();
}class SubTemplate extends Template{@Overridepublic void code() {//1000以内的质数for (int i=2; i<1000;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);}}}
}

例2

//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {public static void main(String[] args) {BankTemplateMethod btm = new DrawMoney();btm.process();BankTemplateMethod btm2 = new ManageMoney();btm2.process();}
}
abstract class BankTemplateMethod {// 具体方法public void takeNumber() {System.out.println("取号排队");}public abstract void transact(); // 办理具体的业务 //钩子方法public void evaluate() {System.out.println("反馈评分");}// 模板方法,把基本操作组合到一起,子类一般不能重写public final void process() {this.takeNumber();this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码this.evaluate();}
}class DrawMoney extends BankTemplateMethod {public void transact() {System.out.println("我要取款!!!");}
}class ManageMoney extends BankTemplateMethod {public void transact() {System.out.println("我要理财!我这里有2000万美元!!");}
}

练习题
编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个Employee对象的生日,则将该雇员的工资增加100元。
实验说明:
(1)定义一个Employee类,该类包含:
private成员变量name,number,birthday,其中birthday 为MyDate类的对象;abstract方法earnings();
toString()方法输出对象的name,number和birthday。
(2)MyDate类包含:
private成员变量year,month,day ;
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
(3)定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处理。该类包括:private成员变量monthlySalary;
实现父类的抽象方法earnings(),该方法返回monthlySalary值;toString()方法输出员工类型信息及员工的name,number,birthday。
练习3
(4)参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括:
private成员变量wage和hour;
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday。
(5)定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日。当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
提示:
//定义People类型的数组People c1[]=new People[10];
//数组元素赋值
c1[0]=new People(“John”,“0001”,20);
c1[1]=new People(“Bob”,“0002”,19);
//若People有两个子类Student和Officer,则数组元素赋值时,可以使父类类型的数组元素指向子类。
c1[0]=new Student(“John”,“0001”,20,85.0);
c1[1]=new Officer(“Bob”,“0002”,19,90.5)

/*
Employee类,该类包含:
private成员变量name,number,birthday,其中birthday 为MyDate类的对象;abstract方法earnings();
toString()方法输出对象的name,number和birthday。*/public abstract class Employee {private String name;private  int number;private MyDate birthday;public abstract double earnings();public Employee(String name, int number, MyDate birthday) {this.name = name;this.number = number;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "{" +"name='" + name + '\'' +", number=" + number +", birthday=" + birthday.toDateString() +'}';}
}
/*
定义SalariedEmployee类继承Employee类,
实现按月计算工资的员工处理。该类包括:private成员变量monthlySalary;
实现父类的抽象方法earnings(),该方法返回monthlySalary值;
toString()方法输出员工类型信息及员工的name,number,birthday。*/
public class SalariedEmployee extends Employee{private double monthlySalary;//月工资public SalariedEmployee(String name, int number, MyDate birthday) {super(name, number, birthday);}public SalariedEmployee(String name, int number, MyDate birthday,double monthlySalary) {super(name, number, birthday);this.monthlySalary = monthlySalary;}public double getMonthlySalary() {return monthlySalary;}public void setMonthlySalary(double monthlySalary) {this.monthlySalary = monthlySalary;}@Overridepublic double earnings() {return monthlySalary;}public String toString(){return "SalariedEmployee{" + super.toString()+"}";}
}
/*
参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括:
private成员变量wage和hour;
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday。*/
public class HourlyEmployee extends Employee{private double wage;//每个小时的工资private double hour;//月工作小时数public HourlyEmployee(String name, int number, MyDate birthday) {super(name, number, birthday);}public HourlyEmployee(String name, int number, MyDate birthday,double wage,double hour) {super(name, number, birthday);this.hour=hour;this.wage=wage;}public double getWage() {return wage;}public void setWage(double wage) {this.wage = wage;}public double getHour() {return hour;}public void setHour(double hour) {this.hour = hour;}@Overridepublic double earnings() {return wage*hour;}public String toString(){return "HourlyEmployee{" + super.toString()+"}";}
}
/*
定义PayrollSystem类,
创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。
利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日。
当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。*/import java.util.Scanner;public class PayrollSystem {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.print("请输入当前月份:");int month = sc.nextInt();Employee[] emps = new Employee[2];//new的是一个数组,不是对象emps[0]=new SalariedEmployee("Maker",1002,new MyDate(1992,10,24),10000);emps[1]=new HourlyEmployee("Parker",2001,new MyDate(1991,5,6),60,240);for(int i =0 ; i<emps.length;i++){System.out.println(emps[i].toString());System.out.println("月工资为:"+emps[i].earnings());if (month == emps[i].getBirthday().getMonth()){System.out.println("生日快乐!!!,奖励100元");}}}
}
/*
MyDate类包含:
private成员变量year,month,day ;
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日*/
public class MyDate {private int year;private int month;private int day;public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}public String toDateString(){return year +"年"+month+"月"+day+"日";}
}

2、接口

接口的使用
1、接口使用interface来定义

2、在java中,接口和类是并列的两个结构

3、如何定义接口,定义接口中的成员
    3.1、JDK7以前:只能定义全局常量和抽象方法,即public static final、public abstract,书写时可以省略不写
    3.2、JDK8:除了定义全局常量和抽象方法以外,还可以定义静态方法,默认方法

4、接口中不能定义构造器,意味着接口不能实例化。

5、java开发中,接口都通过类去实现(implement)的方式来使用, 如果实现类覆盖了接口中所有的抽象方法,则此实现类就可以实例化, 如果实现类没有覆盖了接口中所有的抽象方法,则此实现类仍为一个抽象类。

6、java类可以实现多个接口---->弥补了java单继承性的局限性。格式如下:

class AA extends BB implements CC,DD,EE...{}     //先写继承,后写实现

接口定义举例

public interface Runner {int ID = 1;void start();public void run();void stop();
}
//等同于
public interface Runner {public static final int ID = 1;public abstract void start();public abstract void run();public abstract void stop();
}

补充例子:

public class InterfaceTest {public static void main(String[] args) {System.out.println(Flyable.MAX_SPEED);System.out.println(Flyable.MIN_SPEED);// Flyable.MIN_SPEED=2;}
}interface Flyable{//全局常量public static final int MAX_SPEED = 7900;//第一宇宙速度int MIN_SPEED = 1;//省略了public static final//抽象方法public abstract void fly();void stop();//省略了public abstract
}class Plane implements Flyable{//接口Flyable@Overridepublic void fly() {System.out.println("飞机飞过天空");}@Overridepublic void stop() {System.out.println("减速停止");}
}abstract class Kite implements Flyable{//只重写了接口的一个方法,没有将接口中的方法全部重写,所以该类为抽象类@Overridepublic void fly() {}
}class Bullet extends Object implements Flyable,Attackable{//继承了Flyable和Attackable,先继承父类,后实现接口@Overridepublic void fly() {}@Overridepublic void stop() {}@Overridepublic void attack() {}
}
//************************************************************

默认为全局常量

7、类和类之间为继承,接口和类之间为实现,接口和接口之间也为继承(多继承)

//接口也可以进行多继承
interface AA{void method1();
}
interface BB{void method();
}
interface CC extends AA,BB{}
class DD implements CC{@Overridepublic void method1() {}@Overridepublic void method() {}
}

8、接口的使用可以体现多态性
9、接口实际上可以看作是一种规范

面试题:抽象类和接口有哪些异同?

左边的例1:

/*
接口的使用
1、接口的使用满足多态性
2、接口实际上就是定义了一种规范
3、开发中,体会面向接口编程*/public class USBTest {public static void main(String[] args) {Computer computer = new Computer();Flash flash = new Flash();computer.transferData(flash);}
}class Computer{public void transferData(USB usb){//USB usb = new Flash();usb.start();System.out.println("具体传输数据的细节");usb.stop();}
}interface USB{//常量:定义了长,宽、最大最小的传输速度等void start();void stop();
}class Flash implements USB{@Overridepublic void start() {System.out.println("U盘开启工作");}@Overridepublic void stop() {System.out.println("U盘结束工作");}
}class Printer implements USB{@Overridepublic void start() {System.out.println("打印机开启工作");}@Overridepublic void stop() {System.out.println("打印机结束工作");}
}

U盘开启工作
具体传输数据的细节
U盘结束工作
打印机开启工作
具体传输数据的细节
打印机结束工作
手机开始工作
具体传输数据的细节
手机结束工作
MP3开始工作
具体传输数据的细节
MP3结束工作
创建接口的匿名实现类

public class USBTest {public static void main(String[] args) {Computer computer = new Computer();//1、创建了接口的非匿名实现类的非匿名对象Flash flash = new Flash();computer.transferData(flash);//2、创建了接口的非匿名实现类的匿名对象computer.transferData(new Printer());//3、创建接口的匿名实现类的非匿名对象USB phone = new USB() {@Overridepublic void start() {System.out.println("手机开始工作");}@Overridepublic void stop() {System.out.println("手机结束工作");}};computer.transferData(phone);//4、创建接口的匿名实现类的匿名对象computer.transferData(new USB() {@Overridepublic void start() {System.out.println("MP3开始工作");}@Overridepublic void stop() {System.out.println("MP3结束工作");}});}
}

接口举例(2)
interface Runner {public void start();public void run();public void stop();
}
class Person implements Runner {public void start() {// 准备工作:弯腰、蹬腿、咬牙、瞪眼
// 开跑}public void run() {// 摆动手臂
// 维持直线方向}public void stop() {// 减速直至停止、喝水。}
}


接口的应用: 代理模式
代理模式是Java开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个对象的访问。

例1:

//接口的应用:代理模式(Proxy)【静态代理】
public class NetWorkTest {public static void main(String[] args) {Server server = new Server();ProxyServer proxyServer = new ProxyServer(server);proxyServer.browse();}
}interface NetWork{public void browse();
}//被代理类
class Server implements NetWork{@Overridepublic void browse() {System.out.println("真实的服务器访问网络");}
}//代理类
class ProxyServer implements NetWork{private NetWork work;public ProxyServer(NetWork work){this.work = work;}public void check(){System.out.println("联网之前的检查工作");}@Overridepublic void browse() {check();work.browse();}
}


例2:

public class StaticProxyTest {public static void main(String[] args) {Star s = new Proxy(new RealStar());s.confer();s.signContract();s.bookTicket();s.sing();s.collectMoney();}
}interface Star {void confer();// 面谈void signContract();// 签合同void bookTicket();// 订票void sing();// 唱歌void collectMoney();// 收钱
}//被代理类
class RealStar implements Star {public void confer() {}public void signContract() {}public void bookTicket() {}public void sing() {System.out.println("明星:歌唱~~~");}public void collectMoney() {}
}
//代理类
class Proxy implements Star {private Star real;//在代理类里创建被代理类的对象public Proxy(Star real) {this.real = real;}public void confer() {System.out.println("经纪人面谈");}public void signContract() {System.out.println("经纪人签合同");}public void bookTicket() {System.out.println("经纪人订票");}public void sing() {//调用被代理类的方法real.sing();}public void collectMoney() {System.out.println("经纪人收钱");}
}

经纪人面谈
经纪人签合同
经纪人订票
明星:歌唱~~~
经纪人收钱

接口应用: 工厂模式

1、无工厂模式

package com.atguigu.pattern.factory.nofactory;interface Car{void run();
}
class Audi implements Car{public void run() {System.out.println("奥迪在跑");}
}
class BYD implements Car{public void run() {System.out.println("比亚迪在跑");}
}
public class Client01 {public static void main(String[] args) {Car a = new Audi();Car b = new BYD();a.run();b.run();}
}

2、简单工厂模式
简单工厂模式,从命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的工厂类。

interface Car {void run();
}
class Audi implements Car {public void run() {System.out.println("奥迪在跑");}
}
class BYD implements Car {public void run() {System.out.println("比亚迪在跑");}
}//工厂类
class CarFactory {//XXXFactory就是XXX工厂:用来造XXX对象的//方式一public static Car getCar(String type) {if ("奥迪".equals(type)) {return new Audi();} else if ("比亚迪".equals(type)) {return new BYD();} else {return null;}}
//方式二
// public static Car getAudi() {// return new Audi();
// }
//
// public static Car getByd() {// return new BYD();
// }
}
public class Client02 {//调用者public static void main(String[] args) {Car a = CarFactory.getCar("奥迪");a.run();Car b = CarFactory.getCar("比亚迪");b.run();}
}


调用者只要知道他要什么,从哪里拿,如何创建,不需要知道。分工,多出了一个专门生产 Car 的实现类对象的工厂类。把调用者与创建者分离。
小结:
简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的实例对象。
缺点:对于增加新产品,不修改代码的话,是无法扩展的。违反了开闭原则(对扩展开放;对修改封闭)。

3、工厂方法模式

为了避免简单工厂模式的缺点,不完全满足 OCP(对扩展开放,对修改关闭)。工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立的模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

interface Car{void run();
}
//两个实现类
class Audi implements Car{public void run() {System.out.println("奥迪在跑");}
}
class BYD implements Car{public void run() {System.out.println("比亚迪在跑");}
}
//工厂接口
interface Factory{Car getCar();
}
//提供了两个工厂类
class AudiFactory implements Factory{//专门造奥迪的工厂public Audi getCar(){return new Audi();}
}
class BydFactory implements Factory{//专门造比亚迪的工厂public BYD getCar(){return new BYD();}
}
public class Client {public static void main(String[] args) {Car a = new AudiFactory().getCar();Car b = new BydFactory().getCar();a.run();b.run();}
}

总结:
简单工厂模式与工厂方法模式真正的避免了代码的改动了?没有。在简单工厂模式中,新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色写死(就像上面的例子一样)。而且产品对象创建条件的改变必然会引起工厂角色的修改。面对这种情况,Java 的反射机制与配置文件的巧妙结合突破了限制——这在Spring 中完美的体现了出来。


接口和抽象类之间的对比

接口面试题:

//程序有没有问题?怎么改?
interface A {int x = 0;
}
class B {int x = 1;
}
class C extends B implements A {public void pX() {//System.out.println(x);//x是不明确的,不清晰的System.out.println(super.x);//1System.out.println(A.x);//0}public static void main(String[] args) {new C().pX();}
}
interface Playable {void play();
}
interface Bounceable {void play();
}
interface Rollable extends Playable,Bounceable {Ball ball = new Ball("PingPang");//省略了public static final,是个常量,不能修改
}class Ball implements Rollable {private String name;public String getName() {return name;}public Ball(String name) {this.name = name;}public void play() {ball = new Ball("Football");//修改了ball,违反了final的不可修改System.out.println(ball.getName());}
}

package IntefaceEver;
/*
定义一个接口用来实现两个对象的比较。
interface CompareObject{
public int compareTo(Object o); //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
}*/public interface CompareObject {//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小public int compareTo(Object o);
}
package IntefaceEver;
/*
定义一个Circle类,声明redius属性,提供getter和setter方法*/public class Circle {private double reduis;public double getReduis() {return reduis;}public void setReduis(double reduis) {this.reduis = reduis;}public Circle(double reduis) {this.reduis = reduis;}public Circle() {}
}
package IntefaceEver;
/*
定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。*/public class ComparableCircle extends Circle implements CompareObject{public ComparableCircle(double reduis) {super(reduis);}@Overridepublic int compareTo(Object o) {if (this == o){return 0;}if (o instanceof ComparableCircle){ComparableCircle c =(ComparableCircle)o;// return (int) (this.getReduis()- c.getReduis());//错误if (this.getReduis()>c.getReduis()) {return 1;}else if (this.getReduis()<c.getReduis()){return -1;}else {return 0;}//当属性radius声明为Double类型时,可以调用包装类的方法}else {//   return 0;throw new RuntimeException("传入的对象不合适");}}
}
package IntefaceEver;
/*
定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。*/public class InterfaceTest {public static void main(String[] args) {ComparableCircle c1 = new ComparableCircle(3.4);ComparableCircle c2 = new ComparableCircle(3.6);int compareValue = c1.compareTo(c2);if (compareValue>0){System.out.println("c1对象大");}else if (compareValue<0){System.out.println("c2对象大");}else{System.out.println("c1和c2一样大");}}}

JDK8 的新特性如下

/** JDK8当中,除了定义全局常量之外,还可以定义静态方法,默认方法*///接口A
public interface CompareA {//静态方法public static void method1() {System.out.println("CompareA:北京");}//默认方法public default void method2() {System.out.println("CompareA:上海");}default void method3() {System.out.println("CompareA:广州");}public default void method4() {System.out.println("CompareA:深圳");}
}
//接口B
public interface CompareB {public default void method4() {//与接口A的method4方法重名System.out.println("CompareB:深圳");}}//父类
public class SuperClass {public void method3() {//与接口A中的method3方法充满System.out.println("SuperClass:广州");}}public class SubClassTest {public static void main(String[] args) {SubClass s = new SubClass();//        s.method1();//知识点1:接口中定义的静态方法,只能通过接口来调用CompareA.method1();//知识点2:通过实现类的对象,可以调用接口中的默认方法//知识点3:如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写后的方法。s.method2();//知识点4:如果子类(实现类)继承的父类和实现的接口中声明了同名同参的方法,//那么在没有重写此方法的情况下,默认调用的是父类的--->类优先原则s.method3();//知识点5:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,//那么在实现类没有重写此方法的情况下,报错--->接口冲突//这种情况,就需要我们必须重写这个方法//s.method4();}}
class SubClass extends SuperClass implements CompareA,CompareB{//实现接口public void method2() {//System.out.println("SubClass:上海");}public void method4() {System.out.println("SubClass:深圳");}//知识点5:如何在子类(或实现类)的方法中调用父类、接口中的方法public void myMethod() {method3();//自己定义的方法super.method3();//调用父类中声明的方法CompareB.super.method4();//调用接口中的默认方法}
}

3、内部类

类的内部成员之五:内部类
1、java中允许将一个类A声明在另一个类B中,则,类A就是内部类,类B为外部类。
2、内部类的分类:成员内部类、局部内部类(方法内、代码块内、构造器内)
3、成员内部类:

一方面:作为外部类的成员,可以调用外部类的结构,可以被static修饰,可以被4种不同权限的修饰符修饰
另一方面:作为一个类(可以被继承,可以被final、abstract修饰),可以声明属性、方法、构造器等。

4、关注以下3个问题

4.1、如何实例化成员内部类的对象
4.2、如何在成员内部类中区分调用外部类的结构
4.3、开发中,局部内部类的使用

public class InnerClassTest {public static void main(String[] args) {//创建AA1的实例(静态成员内部类)Person.AA1 aa1 = new Person.AA1();aa1.say();//创建AA2的实例(非静态成员内部类)
//      Person.AA2 aa2 = new Person.AA2();//错误的,非静态的内部类,需要先将Person实例化Person p = new Person();Person.AA2 aa2 = p.new AA2();aa2.run();aa2.display("AA2_Disolay");}}class Person{String name = "XiaoMing";int  age;public void eat() {System.out.println("吃饭");}//静态成员内部类static class AA1{void say() {System.out.println("说了句话");}}//非静态成员内部类class AA2{String name = "AA2";public AA2(){//内部类的构造器}public void run() {eat();//调用外部类的方法,省略了Person.thisPerson.this.eat();System.out.println("running");}public void display(String name) {System.out.println(name);//方法的形参System.out.println(this.name);//内部类的属性System.out.println(Person.this.name);//外部类的属性}}{//代码块中//局部内部类final class BB{//fianl修饰}}public Person() {//构造器内//局部内部类abstract class CC{//abstrct修饰}}public void method() {//方法体中//局部内部类class DD{}}
}

开发中,内部类的使用

public class InnerClassTest1 {//开发中很少见public void method() {//方法体中//局部内部类class DD{}}//comparable是个接口//返回一个实现了Comparable接口的类的对象public Comparable getComprable() {//创建了实现了Comparable接口的类:局部内部类
//      //方式1:
//      class MyComparable implements Comparable{//
//          @Override
//          public int compareTo(Object arg0) {//              return 0;
//          }
//
//      }
//      return new MyComparable();//方式2:return new Comparable() {@Overridepublic int compareTo(Object o) {return 0;}};}}

day15笔记:抽象类和抽象类方法、接口、内部类相关推荐

  1. 学习笔记——day09(抽象final接口)

    常见面试题 final修饰静态常量进过方法 final 修饰的基本数据类型变量的值 无法进行修改的 final 修饰的引用类型的变量 只保证地址不变 对象中的内容可以发生改变 代码 public cl ...

  2. Java 抽象类和接口内部类及综合

    11.抽象类和接口 1.在JDK1.7中,下述说法中抽象类与接口的区别与联系正确的有哪些? [多选题]全选 您的回答: A.抽象类中可以有普通成员变量,接口中没有普通成员变量. B.抽象类和接口中都可 ...

  3. CoreJava 笔记总结-第六章 接口、lambda表达式与内部类

    文章目录 第六章 接口.lambda表达式与内部类 ==接口== 接口的概念 接口的属性 接口与抽象类 静态和私有方法 默认方法 解决默认方法冲突 接口与回调 `Comparator`接口 对象克隆 ...

  4. 面向对象(final/抽象类/接口/内部类)

    >final 关键字 1.final修饰类,这个类不能被被继承; 2.final修饰变量,这个变量的值不能发生改变,就是常量; 注意: final修饰的变量,必须要初始化赋值,否则报错; 赋值的 ...

  5. java 由接口构造对象_Java学习笔记04——类和对象|抽象和接口|构造方法与继承...

    六.Java类 1.  Java中用关键字class来创建类. 2.  类中属性和方法称为类的成员;类的声明和方法要在同一个文件内,不同于C++. 3.  类的定义: [] class [extend ...

  6. 抽象类+接口+内部类作业题及答案

    抽象类+接口+内部类作业题 一.选择题 Person类和Test类的代码如下所示,则代码中的错误语句是( ).(选择一项) public class Person { public String na ...

  7. 抽象类+接口+内部类作业题

    抽象类+接口+内部类作业题 一. 选择题 1. Person类和Test类的代码如下所示,则代码中的错误语句是(  c  ).(选择一项)   public class Person { public ...

  8. 第三周 Java语法总结__static关键字__代码块__继承__this和super的区别__重写__final关键字__多态__抽象__接口__形参问题__包__权限修饰符__内部类

    文章目录 6.static关键字 1)静态static关键字的特点: 2)关于static关键字的使用注意事项 3)什么时候将变量定义为成员变量: 7.文档说明书: 8.代码块 9.继承 1)继承的概 ...

  9. day03笔记 抽象类 和接口

    今日内容 抽象类 接口 内部类 教学目标 能够写出抽象类的格式 能够写出抽象方法的格式 能说出抽象类的应用场景 写出定义接口的格式 写出实现接口的格式 说出接口中成员的特点 能说出接口的应用场景 能说 ...

最新文章

  1. mysql中int最大多少,int(11)最大長度是多少,MySQL中varchar最大長度是多少(轉)
  2. Apache Hudi x Pulsar Meetup杭州站火爆来袭,实践干货就等你来!
  3. php mysql int string_mysql查出的 int 型字段都是 string
  4. 一招让你拿下seata分布式事务框架,看这篇文章准没错!
  5. VMware实现Android x86 8.1 从安装到使用
  6. pcl里面使用KdTree来搜索
  7. python批量音频转格式_python将mp3格式批量转化为wav格式
  8. C语言 strnlen函数实现
  9. Head First 设计模式中的命令模式 的一个错误
  10. 【Elasticsearch】es fielddata 字段数据
  11. Linux手动配置虚拟机网络的两种方式
  12. 玩转诺基亚5800XM,新手上路指南
  13. 剑指offer17--旋转的方式打印矩阵
  14. PayPal美元和人民币之货币转换问题
  15. Java实现阿拉伯数字转换成中文大写数字,以及中文大写数字到阿拉伯数字的转换。
  16. termux安装numpy,matplotlib,pandas
  17. 5g网站服务器宽带,别装有线宽带了,5G以后,有线宽带将被淘汰
  18. push时git报错 error: failed to push some refs to 'git@gitee.com:git_zn/jianli.git' 解决办法...
  19. 无盘服务器健康度,无盘工作站搭建及日常维护技巧简介
  20. Raspbian上显示韩文并安装韩语输入法

热门文章

  1. Android动态壁纸 Live Wallpaper
  2. CSS-background、渐变
  3. NKD的配置和编写JNI的步骤
  4. 暴风酷播云二期配置_暴风播酷云二期 黑群晖
  5. JAVA后台如何处理客户端提交的二进制图片思路
  6. SARscape数据处理SAR数据笔记——DINSAR微小形变提取
  7. Android之动画全讲-刘志远-专题视频课程
  8. 段正淳是否是一个卑劣的人?
  9. 申请微信公众号的一些流程和注意
  10. 深度学习模型中的参数数量(备忘)