Java抽象类,接口

抽象

1. 抽象类
  • 抽象类不能实例化, 只作为父类让子类去继承实现.
  • 抽象类不一定有抽象方法, 但是有抽象方法的类一定是抽象类. 抽象类可以有普通方法.
  • 一个类继承了抽象类,必须重写所有的抽象方法,或者把这个类也定义成抽象类.

示例

package Warren;  
  
abstract class Person{  
    abstract void show();  
  
    void walk(){  
        System.out.println(" person walk");  
    }  
}  
  
class Student extends Person{  
    @Override //继承并重写抽象方法  
    public void show(){  
        System.out.println("student show");  
    }  
}  
  
public class Main {  
    public static void main(String[] args) {  
        Student s1 = new Student();  
        s1.show();  
        s1.walk();//继承并实现普通方法  
    }  
}
2. 抽象方法
  • 没有方法体,只有方法声明(签名).

示例:

abstract class Shape {
    abstract void draw(); // 抽象方法
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a Circle");
    }//如果不重写,就报错
}

class Rectangle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a Rectangle");
    }//如果不重写,就报错
}

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        circle.draw(); 

        Shape rectangle = new Rectangle();
        rectangle.draw(); 
    }
}
3.模板设计方法
  • 可以减少重复的代码量.
package Warren;  
  
 public abstract class Person {  
     public final void write(){  
         System.out.println("Person write");  
         writeMain();  
         System.out.println("Person write finished");  
     }  
     abstract void writeMain();  
 }

package Warren;  
public class Teacher extends Person {  
  
  
    @Override  
    void writeMain() {  
        System.out.println("teacher write main");  
    }  
  
}

package Warren;  
public class Student extends Person {  
  
  
    @Override  
    void writeMain() {  
        System.out.println("student write main");  
    }  
  
}

package Warren;  
public class Main {  
    public static void main(String[] args) {  
        Student student = new Student();  
        Teacher teacher = new Teacher();  
  
        student.write();  
        System.out.println("-----------");  
        teacher.write();  
    }  
}
  • 模板方法前加final,防止子类重写使其失效.

接口(Interface)

注意点:
  • 接口里面只能有抽象方法和成员变量. 接口里面的方法都是抽象方法(省略了abstract). 成员变量都是常量.
  • 接口不能创建实例化对象.
  • 一个类可以实现多个接口, 一个类实现接口需要重写接口中全部的抽象方法. 或者把这个类也定义成抽象类.
  • 接口中的方法默认使用public修饰,以便于其他类去实现接口中的方法.
  • 接口中的方法和成员变量不能用private修饰,因为接口是为了定义公共的API供其他类去实现.
接口的好处:
  • 弥补了类单继承的不足,一个类可以实现多个接口.
  • 让程序可以面向接口编程. 更好的切换业务实现.

package Warren;  
  
public interface Person {  
    String name="man";  
    String getName();//无论写不写abstract,接口中的方法都是抽象方法  
}

package Warren;   
public class Student implements Person {  
    @Override  
    public String getName() {  
       return name;  
    }  
}

package Warren;  
public class Main {  
    public static void main(String[] args) {  
        System.out.println(Person.name);//可以直接访问到接口中的成员变量  
  
        Student student = new Student();  
        System.out.println(student.getName());  
  
        //Person p=new Person();//报错,接口不能创建实例对象  
  
    }  
}
  • 示例:
//Javabean
package Warren;  
public class Student {  
    private String name;  
    private char gender;  
    private double score;  
  
  
    public Student() {  
    }  
  
    public Student(String name, char gender, double score) {  
        this.name = name;  
        this.gender = gender;  
        this.score = score;  
    }  
  
    /**  
     * 获取  
     * @return name  
     */    public String getName() {  
        return name;  
    }  
  
    /**  
     * 设置  
     * @param name  
     */  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    /**  
     * 获取  
     * @return gender  
     */    public char getGender() {  
        return gender;  
    }  
  
    /**  
     * 设置  
     * @param gender  
     */  
    public void setGender(char gender) {  
        this.gender = gender;  
    }  
  
    /**  
     * 获取  
     * @return score  
     */    public double getScore() {  
        return score;  
    }  
  
    /**  
     * 设置  
     * @param score  
     */  
    public void setScore(double score) {  
        this.score = score;  
    }  
  
    public String toString() {  
        return "Student{name = " + name + ", gender = " + gender + ", score = " + score + "}";  
    }  
}

//定义接口
package Warren;  
  
import java.util.ArrayList;  
  
/*  
 * author: Warren */public interface StudentOperate {  
    void printInfo(ArrayList<Student> students);  
    void printAvg(ArrayList<Student> students);  
}

//实现接口的第一个方法
package Warren;  
  
import java.util.ArrayList;  
  
/*  
 * author: Warren */public class StudentOperateImp implements StudentOperate {  
  
    @Override  
    public void printInfo(ArrayList<Student> students) {  
        for (Student student : students) {  
            System.out.println(student.toString());  
        }  
    }  
  
    @Override  
    public void printAvg(ArrayList<Student> students) {  
        double sum = 0;  
        for (Student student : students) {  
           sum+= student.getScore();  
        }  
        double avg = sum/students.size();  
        System.out.println(avg);  
    }  
}

//第二个方法
package Warren;  
  
import java.util.ArrayList;  
  
/*  
 * author: Warren */public class StudentOperateImp1 implements StudentOperate {  
    int countm=0,countw=0;  
    @Override  
    public void printInfo(ArrayList<Student> students) {  
        for (Student student : students) {  
            if(student.getGender()=='m'){  
                countm++;  
            }  
            if(student.getGender()=='w'){  
                countw++;  
            }  
        }  
        System.out.println("male is "+countm+" "+"woman is "+countw);  
    }  
  
    @Override  
    public void printAvg(ArrayList<Student> students) {  
        double sum = 0,max=students.get(0).getScore(),min=students.get(0).getScore();  
        for (Student student : students) {  
          if(student.getScore()>max){  
              max=student.getScore();  
          }  
          if(student.getScore()<min){  
              min=student.getScore();  
          }  
          sum+=student.getScore();  
        }  
        double avg = (sum-max-min)/(students.size()-2);  
        System.out.println("avg is "+avg);  
    }  
}

//测试类
package Warren;  
  
import java.security.PublicKey;  
import java.util.ArrayList;  
  
public class Main {  
  
  
    public static void main(String[] args) {  
        ArrayList<Student>students=new ArrayList<>();  
        students.add(new Student("james",'m',99));  
        students.add(new Student("talor",'w',19));  
        students.add(new Student("warren",'m',80));  
        students.add(new Student("ricci",'w',80));  
  
        StudentOperate studentOperateImp1=new StudentOperateImp1();//接口的好处在于这,只需修改一处即可完成功能的切换  
  
        studentOperateImp1.printInfo(students);  
        System.out.println("\n");  
        studentOperateImp1.printAvg(students);  
    }  
}
接口新特性:
  • 默认方法:jdk8以后出现,默认被public修饰
public default void  print(){}

不能实例化接口去调用默认方法,需要使用实现类对象调用.
好处是扩展接口的功能时,实现类不用再重写接口中的抽象方法.

  • 私有方法:必须使用private修饰,jdk9开始支持.
private void test(){}

和默认方法一样,需要使用实现类对象调用方法, 可以通过其他方法去调用该方法(因为是private的).

  • 静态方法:必须使用static修饰,默认被public修饰,写不写都可以
static void test(){}
接口的多继承
  • 一个接口可以继承多个接口
interface a{  
    void sayHello();  
}  
interface b {  
    void print();  
}  
//一个接口可以继承多个接口  
interface c extends a,b{  
  
}  
//通过使用接口的多继承,类可以更好的实现接口中的功能  
class d implements c{  
  
    @Override  
    public void sayHello() {  
  
    }  
  
    @Override  
    public void print() {  
  
    }  
}
使用接口的注意事项
  • 一个接口继承多个接口,如果这些接口中的方法签名冲突(重载),则不支持多继承
interface a{  
    void sayHello();  
}  
interface b {  
    String sayHello();  
}  
//报错,此时不支持多继承 
interface c extends a,b{  
  
}
  • 一个类实现多个接口,如果这些接口中的方法签名冲突,则不支持多实现
interface a{  
    void sayHello();  
}  
interface b {  
    String sayHello();  
}  
//一个接口可以继承多个接口  
class c implements a,b{  
      
}
  • 如果一个类在继承了父类的情况下又实现了接口,而且父类和接口中有重名的方法,子类会优先调用父类中的.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值