Java_接口和多态

一.接口

1.概述

  • 比抽象类更加抽象
  • 接口不是类,因为接口中没有构造方法
  • 接口是引用数据类型,主要用来写抽象方法和常量,但是接口中可以写常量,抽象方法,默认方法,私有方法,静态方法
  • 接口使用interface关键字来定义
  • 接口没有构造方法,不能创建对象,需要使用类来实现接口

2.格式

public interface 接口{
    常量
    抽象方法
    默认方法
    私有方法
    静态方法
}

3.接口的实现

public class 实现类名 implements 接口名{
	需要重写接口中的抽象方法
    默认方法可以选择重写或者直接调用
}

4.接口和类的关系

实现关系

  • 单实现: A类 只实现 A接口
  • 多实现: A类 同时实现 A接口,B接口,C接口
public class A[extends 父类名] implements B,C{

}
  • 多层实现: A类 继承 B 类,B类 实现 C接口,D接口

注意事项

  • 如果多个接口中有同名的抽象方法,只需要重写一次
  • 如果多个接口中有同名的默认方法,必须重写一次,不需要加default

注意事项
实现类可以同时继承一个类,实现多个接口,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法

面试题
抽象类和接口的区别是什么?

  • 成员特点不同
    抽象类中的成员比普通类多一种抽象方法(而且抽象方法也可以不写)
    接口中有且只能有抽象方法(JDK1.8以后有带方法体的方法)或者常量
  • 关系特点不同
    参考上个知识点
  • 设计理念不同
    抽象类:定义的是整个继承体系的共性内容
    接口:定义的是整个继承体系的扩展内容

5.接口和接口的关系

继承关系:

  • 单继承: A接口 继承 B接口
  • 多继承: A接口 同时继承 B接口,C接口
  • 多层继承: A接口 继承 B接口,B接口 继承 C接口

注意事项

  • 多个父接口中有重命的抽象方法:子接口无需理会,子接口的实现类只需要实现一次即可
  • 如果多个接口中有同名的默认方法,必须重写一次,需要加default

其他成员特点

  • 接口中,无法定义成员变量,可以定义常量,其值不可以改变,默认使用public static final 修饰
  • 接口中,没有构造方法,不能创建对象
  • 没有静态代码块

二.多态

1.概念

同一种行为,具有多个不同的表现形式

2.前提条件

  • 必须要有继承(或者实现)关系
  • 方法的重写(不重写,无意义)
  • 父类引用指向子类对象(格式体现)

3.格式

父类类型 变量名 = new 子类对象;
变量名.方法名();

4.多态的访问特点

  • 成员变量:
    编译看左边,运行看左边
  • 成员方法:
    静态:编译看左边,运行看左边
    非静态:编译看左边,运行看右边

5.多态的好处和弊端

多态的好处

  • 提高代码的扩展性
  • 提高代码的可维护性

多态在实际开发中常用的应用场景:
父类型可以作为方法的形参的参数类型, 这样可以接受其任意的子类对象.

public static void test(Person p) {   
	p.eat(); 
} 

多态的弊端
父类(父接口)引用 不能直接使用子类的特有成员(成员变量和成员方法).
怎么解决这个问题呢?
可以通过向下转型实现

引用类型转换

  • 向上转型: 父类引用指向子类对象
    多态就是向上转型.
    多态本身就是子类向父类类型转换的过程,这个过程是默认的
父类类型 变量名 = new 子类类型();
Animal a = new cat();
  • 向下转型
    父类类型向子类类型向下转换的过程,这个过程是强制的
    一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型
子类类型 变量名 = (子类类型) 父类变量名;
Cat c = (Cat) a;

6.为什么要转型

调用子类特有的方法

创建Animal类:

abstract class Animal {      
	abstract void eat();  
}  

创建Cat类

class Cat extends Animal {      
	public void eat() {          
		System.out.println("吃鱼");      
	}      
	public void catchMouse() {          
		System.out.println("抓老鼠");      
	}  
}  

创建Dog类

class Dog extends Animal {      
	public void eat() {          
		System.out.println("吃骨头");      
	}      
	public void watchHouse() {          
		System.out.println("看家");      
	}  
}

定义测试类

public class Test {    
	public static void main(String[] args) {        
	// 向上转型          
	Animal a = new Cat();          
	a.eat();                // 调用的是 Cat 的 eat
 
        // 向下转型          
        Cat c = (Cat)a;               
        c.catchMouse();         // 调用的是 Cat 的 catchMouse    
        }  
}

7.转型的异常

public class Test {    
	public static void main(String[] args) {        
		// 向上转型          
		Animal a = new Cat();         
		a.eat();               // 调用的是 Cat 的 eat
		
		// 向下转型          
		Dog d = (Dog)a;               
		d.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】    
		//ClassCastException 类型转换异常
	}  
}

instanceof 关键字

变量名 instanceof 数据类型 
如果变量属于该数据类型,返回true。 
如果变量不属于该数据类型,返回false
public class Test {    
	public static void main(String[] args) {        
		// 向上转型          
		Animal a = new Cat();         
		a.eat();               // 调用的是 Cat 的 eat
 
        // 向下转型          
        if (a instanceof Cat){            
        	Cat c = (Cat)a;                   
        	c.catchMouse();        // 调用的是 Cat 的 catchMouse        
        } else if (a instanceof Dog){            
        	Dog d = (Dog)a;                   
        	d.watchHouse();       // 调用的是 Dog 的 watchHouse       
        }    
    } 
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值