Java只支持单继承,接口解决单继承问题
解决一个类型中需要兼容多种类型特征的问题(接口继承、实现)
不同类型在无法具有共同父类的前提下,仍然能具有相同的特征(用接口实现相同行为的关联)
用接口实现Camera和FourthPhone的关联(方法重写,实现接口和继承类时都有方法重写)
用接口描述不同类型具有相似的行为特征,从而建立关系之后,以接口引用指向实现类的方式去描述不同类型的接口行为的具体表现
接口指向实现类,接口只能调用接口里面的方法,虽然指向了实现类,但无法访问实现类中的其他内容(类似父类子类的向上转型)
/**
* 具有拍照能力的接口
*/
public interface IPhoto {
public void photo();//没有方法体
}
public class Camera implements IPhoto{
// public void photo(){
// System.out.println("相机可以拍照");
// }
@Override
public void photo() {
System.out.println("相机可以拍照");
}
}
~
public class FourthPhone extends ThirdPhone implements IPhoto{
// public void photo(){
// System.out.println("拍照");
// }
public void network(){
System.out.println("上网");
}
public void playGame(){
System.out.println("玩游戏");
}
//方法重写,实现接口和继承类时都有方法重写
@Override
public void photo() {
System.out.println("手机 可以拍照");
}
}
//测试类
//对拍照能力有要求时,此时有两种可以实现的部件
//接口指向实现类,接口只能调用接口里面的方法,虽然指向了实现类,但无法访问实现类中的其他内容~
~
IPhoto ip=new FourthPhone();
ip.photo();//用手机拍照
ip=new Camera();
ip.photo();//用相机拍照
~
接口的语法规则
1、接口限定了一组规范,需要类去实现,接口的访问修饰符一般设为public或默认(系统自动加上public访问权限),不能使用protected
//接口的访问修饰符一般设为public或默认,不能使用protected
public interface INet
2、**接口中的抽象方法可以不写abstract关键字也默认为抽象方法,不加访问修饰符也默认为public,实现类中重写方法时,会自动添加public,重写接口方法时,与重写父类方法类似,访问修饰符允许有变化,即要大于等于重写的方法的访问范围(在实现类中,不同于继承,没有super .访问接口中的内容)
public interface INet {
public void network();
void network();
@Override
public void network() {
System.out.println("上网");
}~
3、当类实现访问接口时,需要去实现接口中的所有抽象方法,否则需要将该类设置为抽象类
4、接口中可定义常量,默认public static final**,接口名.调用或引用名.调用****
接口引用指向具体实现类,接口引用名只能调用接口定义的方法(以及Object派生的内容),但无法访问实现类中的其他内容~
int temp=30;
//测试类
System.out.println(INet.temp);
INet net=new SmartWatch();
System.out.println(net.temp);~
5、接口与实现类中具有同名常量时,使用接口的引用指向实现类时,打印的仍然是接口中自己定义的常量信息,若调用的是实现类的实例,打印的实现类中定义的内部信息
System.out.println(INet.temp);//访问的一定是接口里的temp
INet net=new SmartWatch();
System.out.println(net.temp);//
SmartWatch net=new SmartWatch();
System.out.println(net.temp);/
6、不想实现接口中的部分抽象方法时的解决方案:
(1)默认方法,可以带方法体,JDK1.8
default void connection(){
System.out.println("接口中的默认连接");
}
INet net=new SmartWatch();
net.connection();
``
(2)实现类中不需要它时可以不用管它,重写其他方法即可,不用成为抽象类
(3)用于接口中某些方法对实现类没有意义的场景,默认方法也可以被重写,可通过接口的引用调用
(4)与接口中的其他普通抽象方法类似,系统会给默认方法默认加上public的访问权限,因此在实现类中重写默认方法时,访问修饰符为public,default没有了(系统添加默认方法体,在继承中重写方法时使用的时super.connection(),而在接口中,使用的是接口.super.connection();所以在继承中使用super访问父类中允许访问的内容,在接口实现类中使用接口.super访问接口中允许访问的内容,而静态成员的访问统一都是接口名/父类名.调用)
@Override
public void connection() {
INet.super.connection();//调用接口中默认的方法 INet.只能访问当前接口中的静态成员,+super才能访问其他成员
}~
default void connection(){
System.out.println("接口中的默认连接");
}
INet net=new SmartWatch();
net.connection();
7、静态方法
(1)静态方法可以带方法体,JDK1.8
static void stop(){
System.out.println("接口中的静态方法");
}
INet.stop();
(2)与父类中的静态方法不能被重写,只能被继承同理,接口的实现类无法重写静态方法,可以用接口名调用
多接口中重名默认方法处理
1、多接口实现时,可使用不同的接口引用指向同一个实现类
public class SmartWatch implements INet,IPhoto
IPhoto ip3=new SmartWatch();
ip3.call();
INet ip4=new SmartWatch();
ip4.call();
2、不同接口中具有重名默认方法时,在实现类中添加自己的同名方法,避免冲突
public interface IPhoto {
default void call(){
System.out.println("打电话1");
}
public interface INet {
default void call(){
System.out.println("打电话2");
}
}
public class SmartWatch implements INet,IPhoto{
public void call(){
System.out.println("打电话");
}
}
继承且实现多接口时重名方法冲突处理,默认指向父类派生的方法,没有冲突(与父类引用指向子类实例时不同,子类重写父类方法,向上转型后,调用的是子类中重写的方法
public class ThirdPhone extends SecondPhone{
public void connection(){
System.out.println("三代手机连接");
}
}
public interface IPhoto {
default void connection(){
System.out.println("连接1");
}
public interface INet {
default void connection(){
System.out.println("连接2");
}
}
public class FourthPhone extends ThirdPhone implements IPhoto,INet
INet net4=new FourthPhone();
net4.connection();
IPhoto net5=new FourthPhone();
net5.connection();
ThirdPhone net6=new FourthPhone();
net6.connection();
多接口同名常量处理
1、明确访问的是哪个常量
interface One{
static int x=11;
}
interface Two{
final int x=22;
}
class Three{
public int x=33;
}
public class TestOne implements One,Two{
public void test(){
System.out.println(One.x);
System.out.println(Two.x);
System.out.println(x);//同名冲突
}
public static void main(String[] args) {
new TestOne().test();
}
}
继承且实现多接口时同名常量:当父类中的属性与接口中的常量同名时,实现机制与对同名默认方法的实现机制不同,此时父类中的属性不占优势,只能在子类中定义它独有的x成员
public class TestOne extends Three implements One,Two{
**public int x=44;**
public void test(){
System.out.println(x);//同名常量与同名方法机制不一致,父类中的常量不占优势,只能在子类中定义独有的成员
}
public static void main(String[] args) {
new TestOne().test();
}
}
接口的继承
//接口可多继承,继承的多接口中具有同名默认方法时,子接口需重写该默认方法
public interface ISon extends IFather,IFather2{
@Override
default void run() {
}
@Override
default void say() {
}
default void connection(){
System.out.println("ISon中连接");
}
}