1.接口的定义
在Java中,接口是一种抽象的数据类型,它定义了一个类应该具备的方法集合,而不提供实现。接口通过关键字interface
来定义,可以包含常量和方法的声明。
接口的特点包括:
- 接口中的方法默认是抽象的,不需要使用
abstract
关键字进行修饰。 - 接口可以继承其他接口,使用
extends
关键字进行声明。 - 一个类可以实现一个或多个接口,使用
implements
关键字进行声明。 - 接口中的方法都是公共的,不能使用
private
、protected
等修饰符。 - 接口中的常量默认是
public static final
的,可以被实现类使用。
接口主要用于实现多态和组件间的解耦。通过实现接口,一个类可以具备多个不同的行为,实现类可以根据需要选择实现的接口。同时,接口还可以用于定义组件之间的契约,实现类必须按照接口定义的方法来进行实现,从而保证了组件之间的互通性和可替换性。
以下是一个接口的示例代码:
public interface Printable {
void print();
}
public class Printer implements Printable {
@Override
public void print() {
System.out.println("Printing...");
}
}
在上述代码中,Printable
是一个接口,它定义了一个print()
方法。Printer
类实现了Printable
接口,并实现了print()
方法。
可以看出,接口定义了一个规范,实现类必须按照接口定义的规范来实现方法。这样,即使使用不同的实现类,我们也可以通过调用接口定义的方法来使用它们的功能,而不需要关心具体实现的细节。
2.代码中的体现
同样拿上一个抽象类中动物,猫,狗,人的例子
public interface Animal {
String type = "动物";
void eat();
void sport();
void sleep();
}
这段代码定义了一个接口Animal
,它包含以下成员:
type
是一个常量字段,值为字符串"动物"。接口中的字段默认为public static final
,即常量。eat()
是一个抽象方法,没有实现体。实现该接口的类需要重写这个方法。sport()
是一个抽象方法,没有实现体。实现该接口的类需要重写这个方法。sleep()
是一个抽象方法,没有实现体。实现该接口的类需要重写这个方法。
接口是一种规范或契约,它定义了一组方法的签名,但没有实现。实现接口的类需要提供方法的具体实现。在这个例子中,Animal
接口定义了一组动物的行为,通过实现这个接口,其他类可以具体实现各自的动物行为。
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sport() {
System.out.println("猫会上树");
}
@Override
public void sleep() {
System.out.println("猫会上树");
}
}
这段代码定义了一个Cat
类,它实现了Animal
接口。实现接口的类需要提供接口中定义的所有方法的具体实现。
在这个例子中,Cat
类重写了Animal
接口中的三个方法:eat()
、sport()
和sleep()
。
eat()
方法被重写为打印输出"猫吃鱼"。sport()
方法被重写为打印输出"猫会上树"。sleep()
方法被重写为打印输出"猫会上树"。
通过实现Animal
接口并提供方法的具体实现,Cat
类定义了一个具体的动物行为,即猫的吃、运动和睡觉的行为。
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sport() {
System.out.println("狗会跑");
}
@Override
public void sleep() {
System.out.println("狗会睡");
}
}
public class Person implements Animal{
@Override
public void eat() {
System.out.println("人吃饭");
}
@Override
public void sport() {
System.out.println("人会跳绳");
}
@Override
public void sleep() {
System.out.println("人会睡觉");
}
}
public class Ts {
public static void main(String[] args) {
System.out.println(Cat.type);
Cat cat = new Cat();
cat.eat();
cat.sport();
cat.sleep();
Dog dog = new Dog();
dog.eat();
dog.sport();
dog.sleep();
Person person = new Person();
person.eat();
person.sport();
person.sleep();
}
}
这段代码定义了一个Ts
类,其中包含了一个main
方法。
在main
方法中,首先通过System.out.println(Cat.type);
打印输出了Cat
类中定义的type
变量的值,即"动物"。
然后创建了一个Cat
对象,并调用eat()
、sport()
和sleep()
方法,分别输出"猫吃鱼"、"猫会上树"和"猫会上树"。
接着创建了一个Dog
对象,并调用eat()
、sport()
和sleep()
方法,分别输出"狗吃肉"、"狗会跑"和"狗会睡觉"。
最后创建了一个Person
对象,并调用eat()
、sport()
和sleep()
方法,分别输出"人吃饭"、"人会运动"和"人需要休息"。
通过调用不同对象的方法,可以看到它们各自实现了Animal
接口定义的方法,并根据具体的实现给出了不同的输出结果。
3.Interface 与 abstract
1.首先,还是定义一个动物接口类
public interface Animal {
String type = "动物";
void eat();
void sleep();
void sport();
/**
* 接口中的默认方法用来对接口功能的升级
*/
default void method(){
System.out.println("这是"+type+"接口类");
}
}
2.定义猫类,狗类
public class Cat implements Animal{
@Override
public void eat() {
this.method();
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫睡觉");
}
@Override
public void sport() {
System.out.println("猫上树");
}
}
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃鱼");
}
@Override
public void sleep() {
System.out.println("狗睡觉");
}
@Override
public void sport() {
System.out.println("狗跑");
}
}
3.定义一个“Person”抽象类继承Animal接口
public abstract class Person implements Animal{
public void Method(){
System.out.println("我是抽象继承类中的一个方法");
}
}
这段代码定义了一个名为Person的抽象类,它实现了Animal接口。抽象类不能直接被实例化,只能作为其他类的父类来继承使用。
在这个抽象类中,有一个名为Method的方法,它打印出一行字符串"我是抽象继承类中的一个方法"。
通过实现Animal接口,Person类需要实现接口中定义的所有方法。
4.定义“Teacher”类继承“Person”类
public class Teacher extends Person{
@Override
public void eat() {
System.out.println("教师吃饭");
}
@Override
public void sleep() {
System.out.println("教师睡觉");
}
@Override
public void sport() {
System.out.println("教师教书");
}
}
5.测试类
public class Ts {
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat();
cat.sleep();
cat.sport();
Dog dog = new Dog();
dog.eat();
dog.sleep();
dog.sport();
Teacher teacher = new Teacher();
teacher.eat();
teacher.sleep();
teacher.sport();
teacher.Method();
}
}
输出结果:
4.一个类继承多个接口
1.定义一个“Programmer” 接口
public interface Programmer {
void editCode();
}
2.定义一个“Student”接口
public interface Student {
void learn();
}
3.定义一个“Me”类用来继承“Programmer”和“Student”
public class Me implements Student,Programmer{
@Override
public void editCode() {
System.out.println("我会编码");
}
@Override
public void learn() {
System.out.println("我会学习");
}
}
这段代码定义了一个名为Me的类,它同时实现了Student和Programmer接口。
在Me类中,实现了Student接口中的learn方法和Programmer接口中的editCode方法。learn方法打印出一行字符串"我会学习",editCode方法打印出一行字符串"我会编码"。
通过实现接口,在Me类中需要提供接口中定义的所有方法的具体实现。这样,Me类可以被当作Student和Programmer两种角色使用。
4.定义测试类
public class Ts {
public static void main(String[] args) {
Me me = new Me();
me.learn();
me.editCode();
}
}
注意:
当类中的方法与接口中的默认方法重名时,用接口名.super调用重名方法
public interface Programmer {
void editCode();
default void job(){
System.out.println("程序员的工作是写程序");
}
}
public interface Student {
void learn();
default void job(){
System.out.println("老师的工作是学习");
}
}
public class Me implements Teacher, Programmer {
@Override
public void editCode() {
System.out.println("我会编码");
}
@Override
public void teach() {
System.out.println("我会教书");
}
@Override
public void job() {
Teacher.super.job();
Programmer.super.job();
}
}
测试类
public class Ts {
public static void main(String[] args) {
Me me = new Me();
me.teach();
me.editCode();
me.job();
}
}
5.继承一个类同时继承多接口
1.定义“Programmer”类
public interface Programmer {
void editCode();
default void job(){
System.out.println("程序员的工作是编码");
}
}
2.定义“Teacher”类
public interface Teacher {
void teach();
default void job(){
System.out.println("老师的工作是讲课");
}
}
3.定义“Me”类
public class Me {
private String job;
public Me(String job) {
this.job = job;
}
public String getJob() {
return job;
}
}
4.定义“Student”类继承“Me”类,同时继承“Programmer”“Teacher”接口
public class Student extends Me implements Teacher,Programmer{
public Student(String job) {
super(job);
}
@Override
public void editCode() {
System.out.println(this.getJob()+"学生会编码");
}
@Override
public void teach() {
System.out.println(this.getJob()+"学生会讲课");
}
@Override
public void job() {
Teacher.super.job();
}
}
这段代码定义了一个名为Student的类,它继承了Me类,并且实现了Teacher和Programmer接口。
在Student类中,构造方法使用了super关键字调用父类Me的构造方法,并传入了一个String类型的参数job。
同时,在Student类中重写了editCode方法和teach方法。editCode方法打印出一行字符串,包含了学生的职业和"学生会编码"字样。teach方法也打印出一行字符串,包含了学生的职业和"学生会讲课"字样。
此外,在Student类中还重写了job方法,并使用Teacher.super.job()调用了Teacher接口中的默认方法job。这样,当调用Student类的job方法时,会执行Teacher接口中的默认实现。
通过继承和实现接口,Student类同时拥有了Me类和Teacher、Programmer接口的方法和属性。这样,Student类可以被当作Me类、Teacher接口和Programmer接口的实例来使用。
5.定义测试类
public class Ts {
public static void main(String[] args) {
Student student = new Student("编程讲师");
student.editCode();
student.teach();
student.job();
}
}