13.Java面向对象-接口-内部类

Java面向对象-接口-内部类


一、接口(interface)

1. 理解

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2. 基本内容

   1. 接口,使用interface关键字来定义
 * 2. 接口,是与类并列的结构
 * 
 * 3. jdk7及之前:接口中只能定义全局常量(public static final)和抽象方法(public abstract)。
 * 				常量的public static final可以省略
 * 				抽象方法的public abstract也可以省略
 * 
 *   jdk8中: 接口中还可以定义静态(static)方法和默认(default)方法.
 *   jdk9中:接口中还可以定义私有(private)方法
 *   
 *   明确:接口中没有构造器!接口不可以实例化
 * 
 * 4. 类与接口之间是实现关系:implements
 * 		类实现接口以后,如果实现了接口中的所有的抽象方法,则此类不是抽象类,可以实例化
 * 		如果实现类没有实现接口中的所有的抽象方法的话,则此类就是一个抽象类,不能实例化。	
 * 5. 类可以实现多个接口。比如:class Bullet extends Object implements Flyable,Attackable
 * 	
 * 6. 接口与接口之间是继承关系。而且是可以多继承的!

3. 代码体现

public class InterfaceTest {
	public static void main(String[] args) {
		System.out.println(Flyable.MAX_SPEED);
//		Flyable.MAX_SPEED = 4500;
		
		Plane p = new Plane();
		p.fly();
		
		Flyable f = p;//体现了接口的多态性
		
		method(p);
	}
	
	public static void method(Flyable f){
		f.fly();
	}
}


interface Flyable{ //可以飞的接口
	//常量
	public static final int MIN_SPEED = 1;
	int MAX_SPEED = 7900;//第一宇宙速度
	
	//抽象方法
	public abstract void fly();
	
	void stop();
}


interface Attackable{ 
	void attack();
}

class Plane implements Flyable{//Plane has a Flyable

	@Override
	public void fly() {
		System.out.println("飞行员启动飞机飞行");
	}

	@Override
	public void stop() {
		System.out.println("飞行员控制飞机停止飞行");
	} 
	
}

abstract class Kite implements Flyable{ //Kite has a Flyable
	
}


class Bullet implements Flyable,Attackable,C{

	@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 test1() {
		// TODO Auto-generated method stub
		
	}

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

//*************************************
interface A{
	void test1();
}

interface B{
	void test2();
}

interface C extends A,B{//接口的多继承
	
}

4. 接口体现多态性

class Computer{
	
	public void transferData(USB usb){ //USB usb = new Flash();
		
		usb.start();
		
		System.out.println("usb设备开始进行数据的传输....");
		
		usb.stop();
		
	}
}

interface USB{
	//常量:尺寸(略)
	
	//抽象方法
	public abstract 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("打印机结束工作");
	}
	
}

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

5. 接口的匿名实现类、匿名对象

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

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

			@Override
			public void stop() {
				System.out.println("mp3结束工作");
			}
			
		};
		
		c1.transferData(usb1);
		//4. 创建接口匿名实现类的匿名对象
		c1.transferData(new USB(){

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

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

类似的:抽象类也有同样的使用

public class AbstractTest {
	public static void main(String[] args) {
		Student s1 = new Student();
		
		//创建了抽象类的匿名子类的对象
		Person p1 = new Person(){

			@Override
			public void eat() {
				System.out.println("工人多吃肉!");
			}
			
		};
		
//		Person p2 = new Person(){};
	}
}

abstract class Person{
	
	public abstract void eat();
	
	public void sleep(){
		System.out.println("人睡觉");
	}
}

class Student extends Person{

	@Override
	public void eat() {
		
	}
	
}

6. 练习

面试题1:是否能正常执行

interface A {
    int x = 0;
}
class B {
    int x = 1;
}
class C extends B implements A {
    public void pX() {
        System.out.println(x);
    }
    public static void main(String[] args) {
        new C().pX();
    }
}

答案:

//编译错误。
//System.out.println(x);
//修改:
System.out.println(super.x);
System.out.println(A.x);

面试题2:是否能正常执行

interface Playable {
    void play();
}

interface Bounceable {
    void play();
}

interface Rollable extends Playable, Bounceable {
    Ball ball = new Ball("PingPang");

}
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");
        System.out.println(ball.getName());
    }
}

答案:

Ball类中的play()中的ball不能再被赋值。因为是常量

代码题:

定义一个接口用来实现两个对象的比较。
interface CompareObject{
	public int compareTo(Object o);   //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
 }
定义一个Circle类,声明redius属性,提供getter和setter方法
定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
思考:参照上述做法定义矩形类Rectangle和ComparableRectangle类,在ComparableRectangle类中给出compareTo方法的实现,比较两个矩形的面积大小。

答案:


public interface CompareObject {
	// 若返回值是 0,代表相等; 若为正数,代表当前对象大;负数代表当前对象小
	public int compareTo(Object o); 
}
/*
 * 定义一个Circle类,声明redius属性,提供getter和setter方法
 */
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;
	}

	@Override
	public String toString() {
		return "Circle [radius=" + radius + "]";
	}
	
}
/*
 * 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
 * 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
 */
public class ComparableCircle extends Circle implements CompareObject {

	
	public ComparableCircle() {
		super();
	}

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

	@Override
	public int compareTo(Object o) {
		if(o == this){
			return 0;
		}
		
		if(o instanceof ComparableCircle){
			ComparableCircle c = (ComparableCircle)o;
			//不够准确的情况:
//			return (int) (this.getRadius() - c.getRadius());
			
			//写法一:
//			if(this.getRadius() > c.getRadius()){
//				return 1;
//			}else if(this.getRadius() < c.getRadius()){
//				return -1;
//			}else{
//				return 0;
//			}
			//写法二:
			return Double.compare(this.getRadius(), c.getRadius());
			
		}else{
			//形参o不是一个ComparableCircle类型的对象
			return -2;
//			throw new RuntimeException("输入的类型不匹配");
		}
	}

}
/*
 * 定义一个测试类InterfaceTest,
 * 创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
 */
public class InterfaceTest {
	public static void main(String[] args) {
		ComparableCircle c1 = new ComparableCircle(2.3);
		ComparableCircle c2 = new ComparableCircle(2.4);
		
		int compareValue = c1.compareTo(c2);
		System.out.println(compareValue);
		
		//语法错误的
//		c1.getRadius() += 2; //c1.getRadius() = c1.getRadius() + 2;
//		c1.compareTo(c2) += 3;
		
	
	}
}

7. 接口的应用之一

  • 代理模式
  • 工厂方法模式

8. java8中的新特性

//从java8开始,可以在接口中定义静态方法和默认方法。
public interface CompareA {
	
	public static void method1(){
		System.out.println("CompareA:北京");
	}
	
	public default void method2(){
		System.out.println("CompareA:上海");
	}
	//如下的方法也是public,只是省略了
	default void method3(){
		System.out.println("CompareA:深圳 ");
	}
	
	default void method4(){
		System.out.println("CompareA:广州 ");
	}
}
public interface CompareB {
	default void method3(){
		System.out.println("CompareB:深圳 ");
	}
}

public class SuperClass {
	
	public void method4(){
		System.out.println("SuperClass:广州");
	}
}
public class SubClass extends SuperClass implements CompareA,CompareB{
	
	//重写了接口中的method2()方法
	public void method2(){
		System.out.println("SubClass:上海");
	}
	
	public void method3(){
		System.out.println("SubClass:深圳 ");
	}
	
	public void method4(){
		System.out.println("SubClass:广州");
	}
	
	public void method(){
		method4();//调用本类重写的方法
		super.method4();//调用父类中被重写的方法
		CompareA.super.method3();//调用接口CompareA中的method3()
		CompareB.super.method3();//调用接口CompareB中的method3()
	}
}

public class InterfaceTest {
	public static void main(String[] args) {
		//知识点1:通过接口调用其内部的静态方法。但是实现类不可以调用其静态方法
		CompareA.method1();
//		SubClass.method1();
		
		//知识点2:通过实现类的对象调用接口中的默认方法
		SubClass sub = new SubClass();
		sub.method3();
		//知识点3:如果实现类重写了接口中的默认方法,则实现类对象调用的就是重写以后的方法
		sub.method2();
		
		//知识点4:如果实现类实现了两个以上的接口。而至少有两个接口中定义了同名同参数的默认方法,则实现类
		//必须重写此方法。否则,报异常--->接口冲突
		
		//知识点5:如果子类(或实现类)继承的父类和实现的接口中定义了同名同参数的方法,则不会报冲突问题
		//在子类(或实现类)没重写此方法的情况下,默认调用的是父类中的方法。--->类优先原则
		sub.method4();
		
		System.out.println();
		
		//知识点6:如何在实现类中调用接口的被重写的默认方法
		sub.method();
	}
	
	
}

四、类的成员之五:内部类(InnerClass)

1. 基本内容

1. 理解:我们可以在一个类A的内部定义另一个类B,则此时类B就称为类A的内部类,类A就称为类B的外部类
 * 
 * 2. 内部类的分类:成员内部类 (静态的、非静态的)   vs  局部内部类(方法内、代码块内、构造器内)
 * 
 * 3. 成员内部类的理解:
 * 		3.1 成员内部类作为一个类:
 * 			> 内部可以定义属性、方法、构造器、代码块、内部类
 * 			> 可以被abstract修饰,表示不能实例化
 * 			> 可以被final修饰,表示不能被继承
 * 
 * 		3.2 成员内部类作为外部类的成员:
 * 			> 可以被4种权限修饰符修饰
 * 			> 可以被static修饰
 * 			> 可以调用外部类的结构(主要是属性、方法)
  4. 关于内部类需要掌握的三个方面:
 * 	 > 如何创建静态的和非静态的成员内部类的对象
 * 	 > 如何在内部类中调用外部类的成员
 * 	 > 局部内部类在开发中的体现

2. 成员内部类的使用

 * 	 > 如何创建静态的和非静态的成员内部类的对象
 * 	 > 如何在内部类中调用外部类的成员
class Person{
	
	String name = "连志鹏";
	int age;
	
	//成员内部类
	static class Dog{
		
		public void shout(){
			System.out.println("汪~汪~");
		}
	}
	
	class Bird{
		String name = "麻雀";
		public void show(String name){
			System.out.println(name);//黄鹂
			System.out.println(this.name);//麻雀
			System.out.println(Person.this.name);//连志鹏
		}
		
		public void sing(){
			System.out.println("鸟儿在歌唱");
			eat();
			System.out.println(age);//Person.this.age
		}
	}
	
	public void show(){
		System.out.println("name : " +name + ", age : " + age);
	}
	
	public void eat(){
		System.out.println("人吃饭");
	}
	
}
public class OuterClass {
	public static void main(String[] args) {
		//创建静态的成员内部类的对象
		Person.Dog dog = new Person.Dog();
		dog.shout();
		//创建非静态的成员内部类的对象
		Person p1 = new Person();
		p1.age = 12;
		Person.Bird bird = p1.new Bird();
		bird.sing();
		
		bird.show("黄鹂");
	}
}

3. 局部内部类的使用

//局部内部类在开发中的体现
public class OuterClass1 {
	
	public void method(){
		//局部内部类
		//此种情况在开发中很少见
		class A{
			
		}
	}
	
	
	//返回接口实现类的对象
	public Comparable getComparable(){
		
		//方式一:声明一个接口的实现类
//		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;
			}
			
		};
		
		/*
		 * 
		 * button.setOnClick(new ClickListener(){
		 * 		public void onClick(){
		 * 			//当点击按钮时,希望触发的操作
		 * 		}
		 * });
		 * 
		 * 
		 * 
		 */
	}
	
}

4. 关于内部类编译后生成的字节码文件

在这里插入图片描述

对应的类为:

class Person{
	
	String name = "连志鹏";
	int age;
	
	//成员内部类
	static class Dog{
		
		public void shout(){
			System.out.println("汪~汪~");
		}
	}
	
	class Bird{
		String name = "麻雀";
		public void show(String name){
			System.out.println(name);//黄鹂
			System.out.println(this.name);//麻雀
			System.out.println(Person.this.name);//连志鹏
		}
		
		public void sing(){
			System.out.println("鸟儿在歌唱");
			eat();
			System.out.println(age);//Person.this.age
		}
	}
	
	public void show(){
		System.out.println("name : " +name + ", age : " + age);
	}
	
	public void eat(){
		System.out.println("人吃饭");
	}
	
	
	//********************************
	public void method(){
		
		//局部内部类
		class A{}
		
	}
	
	{
		//局部内部类
		class A{}
	}
	
	public Person(){
		//局部内部类
		class C{}
	}
	
	
	
}

五、面向对象的小结

  1. 类与对象的理解和关系

  2. 面向对象编程的思路:

    • 创建类
    • 创建对象
    • 通过"对象.属性"或"对象.方法"的方式进行功能的调用

    声明:针对于工具类等结构,通常内部都是定义静态的属性或方法,直接通过类进行调用。

  3. 主线一:类的内部结构

    1. 属性
      1. 属性 vs 局部变量
    2. 方法(最重要)
      1. 方法的声明
      2. 方法的重载
      3. 方法的值传递机制
      4. 递归方法
      5. 方法的重写
    3. 构造器
      1. 创建对象、初始化对象的属性
      2. 构造器可以重载
      3. 构造器内部可以使用this(形参列表) 或 super(形参列表)
    4. 代码块
      1. 作用:初始化类或对象的基本信息
      2. 分类
    5. 内部类
      1. 了解
      2. 成员内部类的使用
  4. 主线二 :面向对象的三大特征

    1. 封装性
      1. 狭义:private属性 public的getter()\setter()
      2. 广义:体现为4种权限修饰符
    2. 继承性
      1. 类的继承性:单继承
      2. 接口的继承性:多继承
    3. 多态性(难点)
      1. 子类对象的多态性
  5. 主线三:关键字的使用

    1. this

    2. import

    3. package

    4. super

    5. static

    6. final

    7. abstract

    8. interface

六、小结

  • 接口(interface),与类(class)并列的结构

    • 让类去实现(implements)接口,同时需要重写(或实现)接口中的抽象方法

    • 类可以实现多个接口

    • 接口,体现的是一种规范。比如:Serializable:可序列化;Comparable:可比较大小的

      class String implements java.io.Serializable, Comparable
      
    • 接口,内部只能定义全局常量和抽象方法 —jdk7及之前

      • jdk8中,可以定义静态方法、默认方法
      • jdk9中,可以定义私有方法
    • 接口与实现类之间存在多态性

      • 比如:public void compare(Comparable c){}
  • 内部类

    • 实际开发中,使用较少
    • 理解:内部类的分类:成员内部类、局部内部类
    • 如何实例化成员内部类
    • 在成员内部类中如何调用外部类的结构:**外部类.this.**外部类的结构
    • 局部内部类的使用:常常在方法内部提供接口的匿名实现类的对象。
  • 题目:你是如何理解面向对象三大特征的? —> 你是如何理解面向对象编程思想的?

    • 封装性:封装结构到类中;4种权限修饰符修饰类及类的内部结构,体现可见性的大小;举例
    • 继承性:继承性的好处;类的单继承性
    • 多态性:子类对象的多态性+虚方法调用;举例;如果没有多态性,抽象类和接口的声明就没有意义!
  • 题目:“万事万物皆对象”,你是怎么理解的?

    • 用java语言编写项目、描述客观世界,都需要由类派生的对象去刻画
    • 层次一:字符串:String,数值类型:包装类,日期:Date,。。。。
    • 层次二:文件:File;IP地址:InetAddress ; 具体网址:URL
    • 层次三:Java语言与其他语言的交互:XML 、数据库、。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值