Java学习笔记4

Java 接口

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口实现和类继承的规则不同,为了数据的安全,继承时一个类只有一个直接父类,也就是单继承,但是一个类可以实现多个接口,接口弥补了类的不能多继承缺点,继承和接口的双重设计既保持了类的数据安全也变相实现了多继承。

Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所以Java接口比Java抽象类更抽象化。但是接口不是类,不能使用new 运算符实例化一个接口。如 x=new comparable(…);//这个是错误来的。但是可以声明接口变量Comparable x; //这是允许的。

Java接口的方法只能是抽象的和公开的,Java接口不能有构造器,Java接口可以有public、static和final属性。即接口中的属性可以定义为 public static final int value=5; [1]

接口把方法的特征和方法的实现分割开来。这种分割体现在接口常常代表一个角色,它包装与该角色相关的操作和属性,而实现这个接口的类便是扮演这个角色的演员。一个角色由不同的演员来演,而不同的演员之间除了扮演一个共同的角色之外,并不要求其它的共同之处。

定义接口格式:
[public]interface 接口名称 [extends父接口名列表]
{
//静态常量
[public] [static] [final] 数据类型变量名=常量值;
//抽象方法
[public] [abstract] [native] 返回值类型方法名(参数列表);
}
实现接口格式:
[修饰符] class 类名[extends 父类名] [implements 接口A,接口B,···]
{
类成员变量和成员方法;
为接口A中的所有方法编写方法体,实现接口A;
为接口B中的所有方法编写方法体,实现接口B}
接口的注意事项
  1. 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
  2. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
  3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
  4. 一个接口可以有多个方法,接口文件保存在 .java 结尾的文件中,文件名使用接口名。
    接口的字节码文件保存在 .class 结尾的文件中,接口相应的字节码文件必须在与包名称相匹配的目录结构中。
  5. 接口不能用于实例化对象,也不能有构造方法,接口里的方法必须为抽象方法,接口不能包含除了 static 和 final 变量以外的成员变量。
  6. 接口不是被类继承,而是被类实现,接口可以多继承,子接口可以对父接口的方法和常量进行重写
实现接口

求两个数的和与最大值

public interface jiekou{//定义一个接口
 int summation();    // 完成两个数的相加
 int compare(int one,int two);    // 获取较大的数
}
public class shili implements jiekou
{
	int one;
	int two;
	public shili(int one,int two){//构造方法
		this.one=one;
		this.two=two;
	}
	public int summation()//求和
	{
		return one+two;
	}
	public int compare(int one,int two)//最大值
	{
		if(one>two)
			return one;
		else
			return two;
	}
}
public class Test {
    public static void main(String[] args) {
		// 创建实现类的对象
        shili a=new shili(111,222);
		System.out.println("和:"+a.summation());
		System.out.println("MAX:"+a.compare(111,222));
        
    }
}

运行结果:
请添加图片描述
说明
在该程序中,首先定义了一个 jiekou 的接口,在该接口中只声明了两个未实现的方法,这两个方法需要在接口的实现类中实现。在实现类 shili 中定义了两个私有的属性,并赋予两个属性初始值,同时创建了该类的构造方法。因为该类实现了 shili 接口,因此必须实现接口中的方法。在最后的测试类中,需要创建实现类对象,然后通过实现类对象调用实现类中的方法。

default关键字

方法在使用关键字default后可以有方法体了。

 interface bit
{
	default void a_l()
	{
		System.out.println("111");
	}
	void eat();
}
class bitbit implements bit{
public void eat()
{
	System.out.println("222");
}
}
public class Father1
{
	public static void main(String [] args)
	{
		bit a=new bitbit();
		a.eat();
		a.a_l();
	}
	
}

运行结果:
在这里插入图片描述
以上符合java多态的特性,default使方法有方法体,当一个类去实现这个接口时,可以不用再重写这个方法,若要重写则会覆盖default方法

总之,接口中默认为抽象方法,实现类必须重写所有抽象方法,defalut方法可以不重写。

接口的多继承

在Java中,类的多继承是不合法,但接口允许多继承。

在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。 如下所示:

public interface Hockey extends Sports, Event

以上的程序片段是合法定义的子接口,与类不同的是,接口允许多继承,而 Sports及 Event 可以定义或是继承相同的方法
举个实例来演示一下接口的多继承:

interface Attack
{
	void attack();
}
interface Medic
{
	void medic();
}
class Shootting implements Attack
{
	public void attack()
	{
		System.out.println("步兵可以攻击");
	}
}
class Medicman implements Attack,Medic
{
	public void attack()
	{
		System.out.println("医疗兵也可以射击");
	}
	public void medic()
	{
		System.out.println("医疗兵可以救人");
	}
}
public class Test21
{
	public static void main(String[] agrs)
	{
		Shootting shootting=new Shootting();
		shootting.attack();
		Medicman medicman=new Medicman();
		medicman.medic();
		medicman.attack();
	}
}

运行结果:

步兵可以攻击
医疗兵可以救人
医疗兵也可以射击

如果多个接口有重名的方法

package multiex;

interface A {
    void m();
}
//注意:方法返回值不一样
interface B {
    int m();
}

class C implements A, B {
    public void m() {
        System.out.println("void m()");
    }

    public int m() {
        System.out.println("int m()");
    }
}

public class Test {
    public static void main(String[] args) {
        C c1 = new C();
        c1.m();
    }
}

编译将无法通过:

在这里插入图片描述
方法名+参数(不含返回值类型)唯一确定一个方法。

所以当返回值不同时,Java认为这还是同一个方法,会与其中一个接口的返回类型冲突。导致编译错误。
如果返回类型相同,那么就是一个方法,实现类实现这一个方法一次就好了。
同理,在继承中子类和父类的方法名和参数若相同,返回值也必须相同
方法的继承与属性的继承有很大的不同,属性任何继承方式均可,而方法则有各种限制,于是在这里做了一个简单的总结:

1、修饰符相同的方法覆盖,即只改内部,不改外部。

2、访问权限不同的方法覆盖,子类只能相对父类越来越宽松,例如父类是public,子类就不能是缺省或protect,private。

3、返回值的类型覆盖,只允许相容的返回类型,例如不能将返回值为int型改为double型,但是复合类型则例外。

4、final的方法覆盖,只能是父类无,子类有,而不能是父类有,子类无。

5、static(静态)的方法覆盖不能有任何变动,即父类有,子类必须有,父类无,子类也必须无。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值