Java学习路线:day15

   日期:2020-05-08     浏览:96    评论:0    
核心提示:文章目录第四章 面向对象(下)原文:https://shimo.im/docs/JYXKDWDkYW设计模式

文章目录

  • 第四章 面向对象(下)
    • 抽象类与抽象方法
      • 抽象类应用
      • 练习
      • 创建抽象类的匿名子类对象
      • 多态的应用:模板方法设计模式(TemplateMethod)
      • 抽象类的练习
    • 接口(interface)
      • 概述
      • 举例
      • 接口的应用:代理模式(Proxy)
      • 接口的应用:工厂模式
    • Java 8 中关于接口的改进
    • 类的内部成员之五:内部类
      • 匿名内部类
      • 局部内部类的使用注意
    • 面向对象思维导图总结

原文:https://shimo.im/docs/JYXKDWDkYWQWGQPH/
《第四章 面向对象编程(下)》

第四章 面向对象(下)

抽象类与抽象方法

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类


public class AbstractTest {
	public static void main(String[] args) {
		//一旦 Person 类抽象了,就不可实例化
// Person p1 = new Person();
// p1.eat();
		
	}
}

abstract class Creature{
	public abstract void breath();
}

abstract class Person extends Creature{
	String name;
	int age;
	
	public Person(){
		
	}
	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	//不是抽象方法
// public void eat(){
// System.out.println("人吃饭");
// }
	
	//抽象方法
	public abstract void eat();
	
	public void walk(){
		System.out.println("人走路");
	}
}

class Student extends Person{
	public Student(String name,int age){
		super(name,age);
	}
	public void eat(){
		System.out.println("学生应该多吃有营养的。");
	}
	@Override
	public void breath() {
		System.out.println("学生应该呼吸新鲜的无雾霾空气");
	}
}

抽象类应用

抽象类是用来模型化那些父类无法确定全部实现,而是由其子类提供具体实现的对象的类。

问题:卡车(Truck)和驳船(RiverBarge)的燃料效率和行驶距离的计算方法完全不同。Vehicle 类不能提供计算方法,但子类可以。


public abstract class Vehicle{
	public abstract double calcFuelEfficiency();//计算燃料效率的抽象方法
	public abstract double calcTripDistance();//计算行驶距离的抽象方法
}
public class Truck extends Vehicle{
	public double calcFuelEfficiency(){ 
		//写出计算卡车的燃料效率的具体方法
	}
	public double calcTripDistance(){ 
		//写出计算卡车行驶距离的具体方法
	}
}
public class RiverBarge extends Vehicle{
	public double calcFuelEfficiency() { 
		//写出计算驳船的燃料效率的具体方法
	}
	public double calcTripDistance( )  {  
		//写出计算驳船行驶距离的具体方法
	}
}

练习


public abstract class Employee {
	
	private String name;
	private int id;
	private double salary;
	
	public Employee(){
		super();
	}

	public Employee(String name, int id, double salary) {
		super();
		this.name = name;
		this.id = id;
		this.salary = salary;
	}
	
	public abstract void work();	
}
  • Manager 类

public class Manager extends Employee{

	private double bonus;	//奖金
	
	public Manager(double bonus) {
		super();
		this.bonus = 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 Num {

}

abstract class Creature{
	public abstract void breath();
}

abstract class Person extends Creature{
	String name;
	int age;
	
	public Person(){
		
	}
	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	//不是抽象方法
// public void eat(){
// System.out.println("人吃饭");
// }
	
	//抽象方法
	public abstract void eat();
	
	public void walk(){
		System.out.println("人走路");
	}
}

class Student extends Person{
	public Student(String name,int age){
		super(name,age);
	}
	public Student(){

	}
	public void eat(){
		System.out.println("学生应该多吃有营养的。");
	}
	@Override
	public void breath() {
		System.out.println("学生应该呼吸新鲜的无雾霾空气");
	}
}
  • PersonTest 类

public class PersonTest {
	public static void main(String[] args) {
		
		method(new Student());	//匿名对象
		
		Worker worker = new Worker(); 
		method1(worker);	//非匿名的类非匿名的对象
		
		method1(new Worker());	//非匿名的类匿名的对象
		
		System.out.println("*********************");
		
		//创建了一个匿名子类的对象:p
		Person p = new Person(){

			@Override
			public void eat() {
				System.out.println("吃东西");
			}

			@Override
			public void breath() {
				System.out.println("呼吸空气");
			}
			
		};
		method1(p);
		System.out.println("**********************"); 
		//创建匿名子类的匿名对象
		method1(new Person(){

			@Override
			public void eat() {
				System.out.println("吃零食");
			}

			@Override
			public void breath() {
				System.out.println("云南的空气");
			}
			
		});
	}
	
	public static void method1(Person p){
		p.eat();
		p.walk();
	}
	
	public static void method(Student s){
		
	}
}
class Worker extends Person{
	
	@Override
	public void eat() {
	}

	@Override
	public void breath() {
	}
}

多态的应用:模板方法设计模式(TemplateMethod)

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
解决的问题:
》当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
》换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式

  • 例 1

public class TemplateTest {
	public static void main(String[] args) {
		
		SubTemlate t = new SubTemlate();
		
		t.sendTime();
	}
}
abstract class Template{
	
	//计算某段代码执行所需花费的时间
	public void sendTime(){
		
		long start = System.currentTimeMillis();
		
		code();	//不确定部分,易变的部分
		
		long end = System.currentTimeMillis();
		
		System.out.println("花费的时间为:" + (end - start));
	}
	
	public abstract void code();
}

class SubTemlate extends Template{
	
	@Override
	public void code() {
		
		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 万美元!!");
	}
}
  • 模板方法设计模式是编程中经常用得到的模式。各个框架、类库中都有他的影子,比如常见的有:
    • 数据库访问的封装
    • Junit 单元测试
    • JavaWeb 的 Servlet 中关于 doGet/doPost 方法调用
    • Hibernate 中模板程序
    • Spring 中 JDBCTemlate、HibernateTemplate 等

抽象类的练习


  • Employee 类

public abstract class Employee {
	private String name;
	private int number;
	private MyDate birthday;
	
	public Employee(String name, int number, MyDate birthday) {
		super();
		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;
	}

	public abstract double earnings();

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

public class MyDate {
	private int year;
	private int month;
	private int day;
	
	public MyDate(int year, int month, int day) {
		super();
		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 + "日";
	}
}
  • SalariedEmployee 类

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

	@Override
	public double earnings() {
		return monthlySalary;		
	}

	@Override
	public String toString() {
		return "SalariedEmployee [" + super.toString() + "]";
	}	
}
  • HourlyEmployee 类

public class HourlyEmployee extends Employee{
	private int wage;	//每小时的工资
	private int hour;	//月工作的小时数
	
	public HourlyEmployee(String name, int number, MyDate birthday) {
		super(name, number, birthday);
	}

	public HourlyEmployee(String name, int number, MyDate birthday, int wage, int hour) {
		super(name, number, birthday);
		this.wage = wage;
		this.hour = hour;
	}

	@Override
	public double earnings() {
		return wage*hour;
	}

	public int getWage() {
		return wage;
	}

	public void setWage(int wage) {
		this.wage = wage;
	}

	public int getHour() {
		return hour;
	}

	public void setHour(int hour) {
		this.hour = hour;
	}
	
	public String toString(){
		return "HourlyEmployee[" + super.toString() + "]"; 
	}
}
  • PayrollSystem 类
import java.util.Calendar;
import java.util.Scanner;

public class PayrollSystem {
	public static void main(String[] args) {
		//方式一:
// Scanner scanner = new Scanner(System.in);
// System.out.println("请输入当月的月份:");
// int month = scanner.nextInt();
		
		//方式二:
		Calendar calendar = Calendar.getInstance();
		int month = calendar.get(Calendar.MONTH);//获取当前的月份
// System.out.println(month);//一月份:0
		
		Employee[] emps = new Employee[2];
		
		emps[0] = new SalariedEmployee("马良", 1002,new MyDate(1992, 2, 28),10000);
		emps[1] = new HourlyEmployee("博西", 2001, new MyDate(1991, 1, 6),60,240);
		
		for(int i = 0;i < emps.length;i++){
			System.out.println(emps[i]);
			double salary = emps[i].earnings();
			System.out.println("月工资为:" + salary);
			
			if((month+1) == emps[i].getBirthday().getMonth()){
				System.out.println("生日快乐!奖励 100 元");
			}
			
		}
	}
}

接口(interface)

概述

  • 一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java 不支持多重继承。有了接口,就可以得到多重继承的效果。
  • 另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有 is-a 的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3 机、手机、数码相机、移动硬盘等都支持 USB 连接。
  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要…则必须能…”的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系
  • 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。


public class InterfaceTest {
	public static void main(String[] args) {
		System.out.println(Flayable.MAX_SPEED);
		System.out.println(Flayable.MIN_SPEED);
	}
}
interface Flayable{
	
	//全局变量
	public static final int MAX_SPEED = 7900;	
	int MIN_SPEED = 1;//省略了 public static final 
	
	//抽象方法
	public abstract void fly();
	
	void stop();//省略了 public abstract 
	//Interfaces cannot have constructors
// public Flayable(){
// 
// } 
}
interface Attackable{
	void attack();
}

class Plane implements Flayable{

	@Override
	public void fly() {
		System.out.println("飞机通过引擎起飞");
		
	}

	@Override
	public void stop() {
		System.out.println("驾驶员减速停止");
	}
	
}
abstract class Kite implements Flayable{

	@Override
	public void fly() {
		
	}
}

class Bullet extends Object implements Flayable,Attackable,CC{

	@Override
	public void attack() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void method1() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void method2() {
		// TODO Auto-generated method stub
		
	}
}

/
public class USBTest {
	public static void main(String[] args) {
		
		Computer com = new Computer();
		//1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();
		com.transferData(flash); 
		//2. 创建了接口的非匿名实现类的匿名对象
		com.transferData(new Printer());
		//3. 创建了接口的匿名实现类的非匿名对象
		USB phone = new USB(){

			@Override
			public void start() {
				System.out.println("手机开始工作");
			}

			@Override
			public void stop() {
				System.out.println("手机结束工作");
			}
			
		};
		com.transferData(phone);
		//4. 创建了接口的匿名实现类的匿名对象
		com.transferData(new USB(){
			@Override
			public void start() {
				System.out.println("mp3 开始工作");
			}

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

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("打印机结束工作");
	}
	
}

接口的应用:代理模式(Proxy)

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


public class NetWorkTest {
	public static void main(String[] args) {
		
		Server server = new Server();
// server.browse();
		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();
	}
	
}
  • 应用场景:
    • 安全代理:屏蔽对真实角色的直接访问。
    • 远程代理:通过代理类处理远程方法调用(RMI)
    • 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象

比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有 100MB,在打开文件时,不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用 proxy 来进行大图片的打开。

  • 分类
    • 静态代理(静态定义代理类)
    • 动态代理(动态生成代理类)
      • JDK 自带的动态代理,需要反射等知识
public class StaticProxyTest {

	public static void main(String[] args) {
		Proxy 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("经纪人收钱");
	}
}

接口的应用:工厂模式

拓展:工厂设计模式.pdf

  • 接口和抽象类之间的对比
No. 区别点 抽象类 接口
1 定义 包含抽象方法的类 主要是抽象方法和全局常量的集合
2 组成 构造方法、抽象方法、普通方法、常量、变量 常量、抽象方法、(jdk8.0:默认方法、静态方法)
3 使用 子类继承抽象类(extends) 子类实现接口(implements)
4 关系 抽象类可以实现多个接口 接口不能继承抽象类,但允许继承多个接口
5 常见设计模式 模板方法 简单工厂、工厂方法、代理模式
6 对象 都通过对象的多态性产生实例化对象
7 局限 抽象类有单继承的局限 接口没有此局限
8 实际 作为一个模板 是作为一个标准或是表示一种能力
9 选择 如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限

在开发中,常看到一个类不是去继承一个已经实现好的类,而是要么继承抽象类,要么实现接口。
-【面试题】排错:

interface A {
	int x = 0;
}
class B {
	int x = 1;
}
class C extends B implements A {
	public void pX() {
// 编译不通过,x 不明确
		System.out.println(x);
// System.out.println(super.x); //1
// System.out.println(A.x);//0
	}
	public static void main(String[] args) {
		new C().pX();
	}
}
  • 排错 2:
interface Playable {
	void play();
}
interface Bounceable {
	void play();
}
interface Rollable extends Playable, Bounceable {
	Ball ball= new Ball("PingPang"); //省略了 public static final
}
public 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"); //The final field Rollable.ball cannot be assigned 
		System.out.println(ball.getName());
	}
}
  • 练习

  • CompareObject 类


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

public class Circle {
	
	private Double radius;

	public Double getRadius() {
		return radius;
	}

	public void setRadius(Double radius) {
		this.radius = radius;
	}

	public Circle() {
		super();
	}

	public Circle(Double radius) {
		super();
		this.radius = radius;
	}
		
}
  • ComparableCircle 类

public class ComparableCircle extends Circle implements CompareObject{

	public ComparableCircle(double radius) {
		super(radius);
	}
	@Override
	public int compareTo(Object o) {
		if(this == o){
			return 0;
		}
		if(o instanceof ComparableCircle){
			ComparableCircle c = (ComparableCircle)o;
			//错误的写法
// return (int)(this.getRedius() - c.getRedius());
			//正确的方式一:
// if(this.getRadius() > c.getRadius()){
// return 1;
// }else if(this.getRadius() < c.getRadius()){
// return -1;
// }else{
// return 0;
// }
			//当属性 radius 声明为 Double 类型时,可以调用包装类的方法
			//正确的方式二:
			return this.getRadius().compareTo(c.getRadius());
		}else{
			return 0;
// throw new RuntimeException("传入数据类型不匹配");
		}
	}
}
  • InterfaceTest 类

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("两个一样的");
		}
		
		int compareValue1 = c1.compareTo(new String("AA"));
		System.out.println(compareValue1);
	}
}

Java 8 中关于接口的改进

Java 8 中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。

静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像 Collection/Collections 或者 Path/Paths 这样成对的接口和类。

默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。比如:java 8 API 中对 Collection、List、Comparator 等接口提供了丰富的默认方法。

  • 例1
  • interface 类

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:杭州");
	}
}
  • SubClassTest 类
public class SubClassTest {

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

interface Filial {// 孝顺的
	default void help() {
		System.out.println("老妈,我来救你了");
	}
}

interface Spoony {// 痴情的
	default void help() {
		System.out.println("媳妇,别怕,我来了");
	}
}

class Father{
	public void help(){
		System.out.println("儿子,救我媳妇!");
	}
}

class Man extends Father implements Filial, Spoony {

	@Override
	public void help() {
		System.out.println("我该就谁呢?");
		Filial.super.help();
		Spoony.super.help();
	}
	
}

类的内部成员之五:内部类

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。


public class InnerClassTest {
	public static void main(String[] args) {
		
		//创建Dog实例(静态的成员内部类)
		Person.Dog dog = new Person.Dog();
		dog.show();
		
		//创建Bird实例(非静态的成员内部类)
// Person.Bird bird = new Person.Bird();
		Person p = new Person();
		Person.Bird bird = p.new Bird();
		bird.sing();
		
		System.out.println();
		
		bird.display("喜鹊");
	}
}
class Person{
	String name = "李雷";
	int age;
	
	public void eat(){
		System.out.println("人,吃饭");
	}
	
	//静态成员内部类
	static class Dog{
		String name;
		int age;
		
		public void show(){
			System.out.println("卡拉是条狗");
// eat();
		}
	}
	
	//非静态成员内部类
	class Bird{
		String name = "杜鹃";
		public Bird(){
			
		}
		
		public void sing(){
			System.out.println("我是一只猫头鹰");
			Person.this.eat();//调用外部类的非静态属性
			eat();
			System.out.println(age);
		}
		
		public void display(String name){
			System.out.println(name);	//方法的形参
			System.out.println(this.name);	//内部类的属性
			System.out.println(Person.this.name);	//外部类的属性
		}
	}
	public void method(){
		//局部内部类
		class AA{
			
		}
	}
	
	{
		//局部内部类
		class BB{
			
		}
	}
	
	public Person(){
		//局部内部类
		class CC{
			
		}
	}
}
  • InnerClassTest1类
public class InnerClassTest1 {
	
// 开发中很少见
	public void method(){
// 局部内部类
		class AA{
			
		}
	}
	
// 返回一个实现了Comparable接口的类的对象
	public Comparable getComparable(){
		
// 创建一个实现了Comparable接口的类:局部内部类
		//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
// 
// }
// 
// return new MyComparable();
		
		//方式二:
		return new Comparable(){


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

匿名内部类


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显卡";
			}
		});
	}
}

局部内部类的使用注意

public class InnerClassTest {
	
// public void onCreate(){
// 
// int number = 10;
// 
// View.OnClickListern listener = new View.OnClickListener(){
// 
// public void onClick(){
// System.out.println("hello!");
// System.out.println(number);
// }
// 
// }
// 
// button.setOnClickListener(listener);
// 
//}

	
	public void method(){
		//局部变量
		int num = 10;
		
		class AA{
			
			public void show(){
// num = 20; //Local variable num defined in an enclosing scope must be final or effectively final
				System.out.println(num);
			}
		}
	}
}

面向对象思维导图总结

  • 导图1

  • 导图2

整个Java全栈系列都是笔者自己敲的笔记。写作不易,如果可以,点个赞呗!

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服