接口的简单认识
接口中不能有 构造器与代码块(静态代码块)
也不能创建对象
public interface MyInterface {
int CONSTANT = 100; // 常量,等同于 public static final int CONSTANT = 100;
void abstractMethod(); // 抽象方法,等同于 public abstract void abstractMethod();
}
public class Test {
public static void main(String[] args) {
System.out.println(A.name);
// A.name="sccaac"//常量不能赋值
//接口不能创建对象
// A a =new A();
}
}
public interface A {
//成员变量(常量)
public static final String name="黑马";
//成员方法(抽象方法)
public abstract void run();
}
接口的实现
接口本身不能直接创建对象,需要定义类来实现接口,并重写接口中的所有抽象方法。一个类可以实现多个接口,实现了接口的类必须提供接口中定义的所有方法。例如:
public class MyClass implements MyInterface {
@Override
public void abstractMethod() {
// 实现接口中的抽象方法
}
}
//实现类(必须重写完接口的所以方法
public class D implements B ,C{
@Override
public void b1() {
}
@Override
public void b2() {
}
@Override
public void c1() {
}
@Override
public void c2() {
}
}
public class Test {
public static void main(String[] args) {
System.out.println("-------------------");
//用了实现类可以创建对象
D d =new D();
d.b1();
}
}
//接口
public interface B {
void b1();
void b2();
}
//接口
public interface C {
void c1();
void c2();
}
接口的好处
理解:Student为父类 singer与driver为接口作为干爸
public class Test {
public static void main(String[] args) {
A a= new A();
a.sing();
System.out.println("-----------");
Singer s1 =new A();// 允许您使用多态性,将 A 类的对象作为 Singer 接口类型处理
Singer s =new B();//接口的好处就是说两个singer我想用a就用a想用b就用b
//方便修改
s.sing();
System.out.println("----------------");
}
}
class B extends Student implements Singer{
@Override
public void sing() {
}
}
//理解:Student为父类 singer与driver为干爸
class A extends Student implements Singer,Driver{
@Override
public void sing() {
}
@Override
public void drive() {
}
}
class Student{
}
interface Singer{
void sing();
}
interface Driver
{
void drive();
}
接口案例
main方法
创建一个班级管理类的对象,调对象的方法
public class Test {
public static void main(String[] args) {
ClassManage class1 =new ClassManage();
class1.printInfo();
class1.printfScore();
}
}
学生类
public class Student {
private String name;
private char sex;
private double score;
public Student() {
}
public Student(String name, char sex, double score) {
this.name = name;
this.sex = sex;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
创建一个班级管理类
注:理论上在班级操作类的方法中将方法写全,直接调用也可以
import java.util.ArrayList;
public class ClassManage {
private ArrayList<Student> students =new ArrayList<>();
//创建一个接口对象
private StudentOperator studentOperator = new StudentOperatorImpI2();
public ClassManage() {
Student s1 = new Student("陶喆",'男',100);
students.add(s1);
// Student s2 = new Student("周杰伦",'男',85.5);
// Student s3 = new Student("林俊杰",'男',70);
// Student s4 = new Student("邓紫棋",'女',95);
// Student s5 = new Student("邓丽君",'女',110);
//简化代码
students.add(new Student("周杰伦",'男',85.5));
students.add(new Student("林俊杰",'男',70));
students.add(new Student("邓紫棋",'女',95));
students.add(new Student("邓丽君",'女',110));
}
//打印全班学生信息
public void printInfo()
{
studentOperator.printAllInfo(students);
}
//打印全班学生成绩
public void printfScore()
{
studentOperator.AllAverageScore(students);
}
}
接口
import java.util.ArrayList;
public interface StudentOperator {
void printAllInfo(ArrayList<Student> students);
void AllAverageScore(ArrayList<Student> students);
}
实现类1
//实现类1
import java.util.ArrayList;
public class StudentOperatorImpI1 implements StudentOperator {
@Override
public void printAllInfo(ArrayList<Student> students) {
System.out.println("----------------全班学生信息-------------------");
for (int i = 0; i <students.size() ; i++) {
Student s =students.get(i);
System.out.println("姓名:"+ s.getName());
System.out.println("性别:"+s.getSex());
System.out.println("成绩:"+s.getScore());
}
System.out.println("---------------------------------------------");
}
@Override
public void AllAverageScore(ArrayList<Student> students) {
double allscore =0.0;
for (int i = 0; i <students.size() ; i++) {
Student s =students.get(i);
allscore += s.getScore();
}
System.out.println("全班的平均分为" + allscore/students.size());
}
}
实现类2
//实现类2
import java.util.ArrayList;
public class StudentOperatorImpI2 implements StudentOperator {
@Override
public void printAllInfo(ArrayList<Student> students) {
System.out.println("---------------------全班学生信息2----------------------");
int sum1 = 0;
int sum2 = 0;
for (int i = 0; i <students.size() ; i++) {
Student s = students.get(i);
System.out.println(s.getName());
System.out.println(s.getSex());
System.out.println(s.getScore());
if(s.getSex() =='男')
{
sum1++;
}
else {
sum2++;
}
}
System.out.println( "性别为男"+sum1);
System.out.println( "性别为女"+sum2);
}
@Override
public void AllAverageScore(ArrayList<Student> students) {
System.out.println("-------------------成绩----------------------");
double Allscore = 0.0;
double max = students.get(0).getScore();
double min = students.get(0).getScore();
for (int i = 0; i <students.size() ; i++) {
Student s = students.get(i);
if(s.getScore()>max)
{
max =s.getScore();
}
if(s.getScore()<min)
{
min =s.getScore();
}
Allscore+= s.getScore();
}
System.out.println("最高分为"+max);
System.out.println("最低分为"+min);
System.out.println("学生平均分为"+(Allscore-max-min)/(students.size()-2));
}
}
从jdk8开始接口新增的方法
在接口中Java帮你把public省去,因为接口是公开使用的
public class Test {
public static void main(String[] args) {
B b =new B();
b.test1();
A.test3();
}
}
下面这些带方法体的好处:增强接口的能力,便于项目的扩展与维护(方法方便直接修改方法,不需要在实现类中进行修改 )
public interface A {
//默认方法 必须用default修饰
//默认方法就是实例方法,是对象的方法所以要创建实现类的对象才可以调用
default void test1(){
System.out.println("默认方法");
test2();//因为为私有方所以只能在这个接口中访问
}
//因为为私有方所以只能在这个接口中访问
//私有方法,用privat修饰(从jdk9开始)
private void test2()
{
System.out.println("私有方法");
}
//静态方法,必须用static修饰,用接口名调用
static void test3(){
System.out.println("静态方法");
}
}
实现类
public class B implements A{
}
接口的多继承
实现类用e完成ABC中的方法原本要implementsABC,现在多继承直接implements D就行
public class Test {
public static void main(String[] args) {
E e =new E();
e.test1();
}
}
interface A{
void test1();
}
interface B{
void test2();
}
interface C{
void test3();
}
interface D extends A,B,C{
}
//实现类用e完成ABC中的方法原本要implementsABC,现在多继承直接implements D就行
class E implements D{
@Override
public void test1() {
}
@Override
public void test2() {
}
@Override
public void test3() {
}
}
接口的其他注意事项
1,一个接口继承多个接口,当多个接口存在方法冲突时(两个方法名相同返回值类型不同),此时不支持多继承
//1,一个接口继承多个接口,当多个接口存在方法冲突时(两个方法名相同返回值类型不同),此时不支持多继承
interface I{
void test4();
}
interface J{
String test4();
}
interface K extends J,I{}
2,一个类实现多个接口,当多个接口存在方法冲突时(两个方法名相同返回值类型不同),此时不支持多继承
//2,一个类实现多个接口,当多个接口存在方法冲突时(两个方法名相同返回值类型不同),此时不支持多继承
interface I{
void test4();
}
interface J{
String test4();
}
class L implements J,I{}
3,一个类既继承了父类又同时实现接口,两者中有同名的默认方法,优先实现父类
//3,一个类既继承了父类又同时实现接口,两者中有同名的默认方法,优先实现父类
public class Test2 {
public static void main(String[] args) {
Z z= new Z();
z.t();
}
}
class F
{
public void t()
{
System.out.println("=======父类的默认方法实现======");
}
}
interface S{
default void t()
{
System.out.println("=============接口的方法实现=========");
}
}
class Z extends F implements S{
}
4.一个类实现了多个接口,多个接口存在同名的默认方法,虽然冲突但是可以在实现类中重写
//一个类实现了多个接口,多个接口存在同名的默认方法,虽然冲突但是可以在实现类中重写
interface IT1{
default void test5 (){
System.out.println("IT1");
}
}
interface IT2
{
default void test5()
{
System.out.println("IT2");
}
}
class N implements IT1,IT2
{
@Override
public void test5() {
System.out.println("自己的");
}
}