栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

day15笔记:抽象类和抽象类方法、接口、内部类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

day15笔记:抽象类和抽象类方法、接口、内部类

抽象类和抽象类方法、接口、内部类
  • 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

    @Override
    public void eat() {
        System.out.println("吃好的!");
    }
    @Override
    public 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;
    }

    @Override
    public void work() {
        System.out.println("管理员工,提高哦公司运行效率!");
    }
}
//CommonEmployee类
public class CommonEmployee extends Employee {
    @Override
    public 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("--------------------");
        
        /

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{

    @Override
    public 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)


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;
    }

    @Override
    public String toString() {
        return "{" +
                "name='" + name + ''' +
                ", number=" + number +
                ", birthday=" + birthday.toDateString() +
                '}';
    }
}

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;
    }

    @Override
    public double earnings() {

        return monthlySalary;
    }

    public String toString(){
        return "SalariedEmployee{" + super.toString()+"}";
    }
}
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;
    }

    @Override
    public double earnings() {
        return wage*hour;
    }
    public String toString(){
        return "HourlyEmployee{" + super.toString()+"}";
    }
}

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 
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
    @Override
    public void fly() {
        System.out.println("飞机飞过天空");
    }
    @Override
    public void stop() {
        System.out.println("减速停止");
    }
}

abstract class Kite implements Flyable{//只重写了接口的一个方法,没有将接口中的方法全部重写,所以该类为抽象类
    @Override
    public void fly() {

    }
}

class Bullet extends Object implements Flyable,Attackable{//继承了Flyable和Attackable,先继承父类,后实现接口
    @Override
    public void fly() {
    }
    @Override
    public void stop() {
    }
    @Override
    public void attack() {
    }
}
/

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{

    @Override
    public void start() {
        System.out.println("U盘开启工作");
    }

    @Override
    public void stop() {
        System.out.println("U盘结束工作");
    }
}

class Printer implements USB{

    @Override
    public void start() {
        System.out.println("打印机开启工作");
    }

    @Override
    public 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() {
            @Override
            public void start() {
                System.out.println("手机开始工作");
            }

            @Override
            public void stop() {
                System.out.println("手机结束工作");
            }
        };
        computer.transferData(phone);

        //4、创建接口的匿名实现类的匿名对象
        computer.transferData(new USB() {
            @Override
            public void start() {
                System.out.println("MP3开始工作");
            }

            @Override
            public 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{

    @Override
    public 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("联网之前的检查工作");
    }

    @Override
    public 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);//1
		System.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;


public interface CompareObject {
    //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
    public int compareTo(Object o);
}
package IntefaceEver;


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;


public class ComparableCircle extends Circle implements CompareObject{

    public ComparableCircle(double reduis) {
        super(reduis);
    }

    @Override
    public 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() 
package IntefaceEver;


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 的新特性如下

 
 //接口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.this
			Person.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() {

			@Override
			public int compareTo(Object o) {
				return 0;
			}
			
		};
	}

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/351359.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号