Java重修之路(九)面向对象之final关键字,抽象类(abstract),接口(interface)

final关键字

这里写图片描述

首先明确,继承的出现打破了封装性,子类继承了父类,就能获得父类的属性和方法,有些封装好的东西就会全部暴露,不安全。所以对于一些特殊的类,为了强制保证其封装性,用final修饰,不允许继承。

这里写图片描述

final修饰的方法不允许重写

这里写图片描述

抽象类

当多个类中出现相同功能,但是功能主体不同,可以进行抽取。只抽取功能定义,不抽取功能主体。


public class Test {

    public static void main(String[] args) {
        new Student().speak();

    }

}

class Person {
    void speak() {
        System.out.println("我是人类");
    };
}

class Teacher extends Person {
    void speak() {
        System.out.println("我是老师");
    }
}

class Student extends Person {
    void speak() {
        System.out.println("我是学生!");
    }
}

如果子类中一定会重写某一方法,那么父类中此方法的主体已经没有任何意义,因为会被覆盖。所以父类中不需要方法主体,于是有:
void speak();
但是这种写法不符合规范,既不是方法,也不是类,于是有了一个关键字abstract 使这种写法合法,于是有:
abstract void speak();
这里只声明了函数名称,没有包含函数主体。
此时,如果实例化对象,然后调用此方法是没有意义的,所以要避免此类被实例化。解决方法就是将此类也用abstract修饰。即表明此类不能被实例化。

总结规律:
1.抽象方法一定在抽象类中。
2.抽象方法和抽象类都必须被abstract关键字修饰。
3.抽象类不可以创建对象,因为里面的抽象方法没有主体,调用没有意义。
4.抽象类中的方法如果要被使用,必须有子类实现所有的抽象方法,然后建立子类对象调用。注意,子类如果没有复写父类的所有抽象方法,那么子类也必须用abstract修饰,子类还是一个抽象类。

实例:


public class Test {

    public static void main(String[] args) {
    }

}

/**
 * 员工类:姓名 工号,工资,以及工作方法
 * 
 * @author Nexts 2016年11月4日
 */
abstract class Worker {
    private String name;
    private String id;
    private double salary;

    public Worker(String name, String id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    abstract void work();
}

/**
 * 经理也属于员工 但是多了一个奖金属性,也必须工作
 * 
 * @author Nexts 2016年11月4日
 */
class Maneger extends Worker {

    private int bonus;// 奖金

    public Maneger(String name, String id, double salary, int bonus) {
        super(name, id, salary);// 父类已经初始化三个变量,子类只需要自己初始化一个
        this.bonus = bonus; // 子类一定会访问父类中构造函数,但是父类的构造函数已经重载。默认的空参数的构造函数已经不存在,需要手动指定
    }

    @Override
    void work() {
    }

}

/**
 * 普通员工
 * 
 * @author Nexts 2016年11月4日
 */
class Emplee extends Worker {

    public Emplee(String name, String id, double salary) {
        super(name, id, salary);
    }

    @Override
    void work() {
    }

}

关于子类父类的构造函数特点,参见上一篇文章: 子类父类构造函数特点


接口

可以简单的理解为:当一个抽象类中所有的方法都是抽象的时候,这个抽象类可以理解为一个接口,接口是一个特殊的抽象类。

这里写图片描述

接口特点:
接口中定义常量和抽象方法。
接口中成员都有固定的修饰符:
常量: public static final
方法: public abstract
如果不写,会默认自动加上。

这里写图片描述

接口可以被类多实现。Java不支持多继承,但是支持多实现。

public interface A {
    void method1();
}

public interface B {
    void method2();
}

class Test implements A, B {

    @Override
    public void method2() {
        // TODO Auto-generated method stub

    }

    @Override
    public void method1() {
        // TODO Auto-generated method stub

    }

}
如果多继承,就需要实现所有接口里面的方法。

为什么不支持多继承,反而支持多实现。
如果继承多个类,不同的类中包含同名方法,但是方法主体不同,子类就不会区分,但是在接口里面,即使多个接口有不同的方法,但是都没有方法主体,在实现接口之后自己写主体,有重名也没有关系。


但是需要注意:多个接口中的同名函数返回值必须相同,如果不相同,它的实现类就不能区分应该实现哪个方法。
多个接口中不能有同名的但是值不同的变量,会冲突。
接口和接口之间支持多继承。


接口中一般存放特有的方法,做功能扩展。共性特征放在父类中通过继承实现,特有功能放在接口中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,我可以给您提供一些思路和参考。 首先,创建视图需要重修的名单,需要根据具体的数据表和业务需求进行设计,以下是一种可能的设计思路: 1. 首先,需要有一个数据表或者视图,记录所有需要重修的学生信息,包括学生姓名、学号、课程名称、课程成绩、是否需要重修等信息。 2. 基于这个数据表,可以使用 SQL 语句创建一个视图,统计所有需要重修的学生信息,例如: ```sql CREATE VIEW view_re_exam AS SELECT student_name, student_id, course_name, course_score FROM student_score WHERE re_exam = 'Y'; ``` 这个视图会返回所有需要重修的学生信息,包括学生姓名、学号、课程名称和课程成绩。 3. 根据具体的业务需求,可以在这个视图上进一步进行统计和分析,例如: - 统计每个学生需要重修的科目数目,并按照从多到少的顺序排序: ```sql SELECT student_name, COUNT(*) AS re_exam_count FROM view_re_exam GROUP BY student_name ORDER BY re_exam_count DESC; ``` - 统计每个科目需要重修的学生数目,并按照从多到少的顺序排序: ```sql SELECT course_name, COUNT(*) AS re_exam_count FROM view_re_exam GROUP BY course_name ORDER BY re_exam_count DESC; ``` - 统计每个年级需要重修的学生数目,并按照从多到少的顺序排序: ```sql SELECT SUBSTR(student_id, 1, 2) AS grade, COUNT(*) AS re_exam_count FROM view_re_exam GROUP BY grade ORDER BY re_exam_count DESC; ``` 以上是一些基本的设计思路和 SQL 示例,具体实现需要根据您的具体业务需求和数据结构进行调整和优化。希望能对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值