【Java】面向对象——基础

Java面向对象——基础

1. 继承——extends

一个class只能继承一个类,即有且仅有一个父类;但一个父类可以被很多子类继承。

  • 父类Person中的nameage属性不需要在子类Student中重复定义
  • protected可以将字段或方法的访问权限控制在了继承树内,比private更适合
    • 这里如果Person类中的name字段定义的是private,那Student类中的name将会报错
public class Main {
    public static void main(String[] args){
         Student stu = new Student();
         stu.hello(); //unnamed
    }
}

public class Person {
    protected String name = "unnamed";
    private int age = 0;
}

public class Student extends Person {
    public void hello(){
        System.out.println(name); //父类Person的name字段,即super.name
    }
}
  • 向上转型没问题,向下转型时为了避免转型出错,最好通过A instanceof B来判断是否成功
Person p = new Student();
if (p instanceof Student) {
    // 只有判断成功才会向下转型:
    Student s = (Student) p; // 一定会成功
}

2. 多态——@override

利用多态,totalTax()只需要和IncomegetTax()打交道就行了,完全不需要知道SalaryGrey的存在,也就是说如果要新增/删除一种收入,只需要让它extends Income,然后@override覆写getTax()方法即可。

  • Tips:用final修饰的方法/类/字段,不能被Overridefinal修饰符有多种作用:
    • final修饰的方法可以阻止被覆写;
    • final修饰的class可以阻止被继承;
    • final修饰的field必须在创建对象时初始化,随后不可修改。
public class Main {
    public static void main(String[] args){
        Income[] incomes = {
                new Income(1000),
                new Salary(10000),
                new Grey(5000)
        };
        System.out.println("总纳税:" + totalTax(incomes));
    }

    public static double totalTax(Income... incomes){
        double sumTax = 0.0;
        for(Income income:incomes){
            sumTax += income.getTax();
        }
        return sumTax;
    }
}

/*
    普通收入
 */
class Income{
    protected double income;

    public Income(double income){
        this.income = income;
    }

    public double getTax(){
        return income * 0.1; //普通收入纳10%的税
    }
}

/*
	工资收入
 */
class Salary extends Income{
    public Salary(double income){
        super(income);
    }

    @Override
    public double getTax() {
        if(income<=5000){ //[0,5000]不纳税
            return 0;
        }else{ //超出5000的部分纳10%的税
            return (income-5000) * 0.1;
        }
    }
}

/*
	灰色收入
 */
class Grey extends Income{
    public Grey(double income) {
        super(income);
    }

    @Override
    public double getTax() {
        return 0;
    }
}

总纳税:600.0

3. 抽象类——abstract

抽象类只能用于被继承,其强迫子类实现其抽象方法,并且这个抽象方法必须没有执行代码

案例:Holiday类如果继承Travel抽象类,那必须要实现buyTickets()这个抽象方法。

public class Main {
    public static void main(String[] args){

        Holiday holiday = new Holiday();
        holiday.buyTickets();
    }
}

/*
	抽象类 Travel
*/
abstract class Travel{
    public abstract void buyTickets(); //抽象方法
}

class Holiday extends Travel{
    @Override
    public void buyTickets() {
        System.out.println("去携程买机票!");
    }
}

4. 接口——interface

所谓interface,就是比抽象类还要抽象的纯抽象接口,因为它不能有实例字段,但是可以有静态字段。

当一个具体的class去实现一个interface时,需要使用implements关键字。

default方法的目的:当给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。(JDK>=1.8)

  • Tips:
    • 一个类只能extends一个class;但是可以implements多个interface
    • 因为接口定义的所有方法默认都是public abstract的,所以这两个修饰符写不写效果都一样
public class Main {
    public static void main(String[] args){

        Holiday holiday = new Holiday();
        holiday.buyTickets();
    }
}

/*
	接口 Travel
*/
interface Travel{
    void buyTickets();

    default String passport() { //default方法,可以不覆写
        return null;
    }
}

class Holiday implements Travel{

    @Override
    public void buyTickets() {
        System.out.println("去携程买机票!");
    }
}

5. 静态方法/字段——static

静态字段属于所有实例共享的字段,即:所有实例共享一个静态字段。它是属于class的。

代码中由于number是静态字段,所以将p1.number赋值为10,那么p2.number也自动为10了。

public class Main {
    public static void main(String[] args){

        Person p1 = new Person("asher",23);
        Person p2 = new Person("Chalice",2);

        p1.number = 10;
        System.out.println(p2.number); //10

    }
}

class Person{
    private String name;
    private int age;
    public static int number; //静态字段 number
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
}
  • Tips:上面代码中不推荐用实例变量.静态字段 p1.number去访问静态字段。因为在Java程序中,实例对象并没有静态字段。在代码中,实例对象能访问静态字段只是因为编译器可以根据实例类型自动转换为类名.静态字段来访问静态对象。推荐用类名来访问静态字段。可以把静态字段理解为描述class本身的字段(非实例字段)。对于上面的代码,更好的写法是:
Person.number = 10;
System.out.println(Person.number); //10

接口的静态字段interface接口虽然不能定义实例字段,但是可以定义静态字段,并且静态字段必须为final类型。实际上因为interface的字段只能是public static final类型,所以我们可以把这些修饰符都去掉:

public interface Person {
    int MALE = 1; //等效于 public static final int MALE = 1;
    int FEMALE = 2; //等效于 public static final int FEMALE = 2;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值