转载

Java笔记04:面向对象基础

继承

Java使用 extends 关键字来实现继承:

class Person {
    private String name;
    private int age;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
}

class Student extends Person {
    // 不要重复name和age字段/方法,
    // 只需要定义新增score字段/方法:
    private int score;

    public int getScore() {...}
    public void setScore(int score) {...}
}

通过继承,子类 Student 获得了父类 Person 已有的字段与方法,节省了重复编写代码的时间。

Java中所有的类都继承自 Object 这个类,除了它自身。

private 关键字修饰的字段,只能在类中被访问,子类也无法访问,为了让子类也能使用父类的字段,要把修饰符改成 protected

多态

在上一篇中讲到构造方法时有提到过 方法签名 的概念,当一个子类与其父类有着相同的方法签名的方法(修饰符、参数、返回值都相同)时,称之为 覆写

注意上篇中讲的重载,并不要求方法签名完全相同,编译器也是根据这个将重载的方法区分开来。覆写则在运行期间动态决定调用的方法,以实现多态。

class Animal {
    public void sound {...}
}
class Cat {
    @Override
    public void sound {
        System.out.println("meow")
    }
}

使用 @Override 可以让编译器帮我们检查覆写是否正确。

final修饰符:

final
final
final

抽象类

有时候,如果父类的方法没有实际意义,能不能不写呢?

class Person {
    public void run(); // Compile Error!
}

上述代码会报错。

如果一个方法只定义方法签名,没有实质内容,可以用 abstract 修饰符把它定义成抽象方法,包含抽象方法的类也必须被声明为 抽象类 (abstract class)。

abstract class Person {
    public abstract void run();
}

抽象类不能被实例化,方法也是空的,这个类用来干什么的呢?抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。因此,抽象方法实际上相当于定义了“规范”。

对于抽象类的子类,我们可以用抽象类型去引用它的子类型:

Person s = new Student();
Person t = new Teacher();
s.run();
t.run();

我们可以直接调用它的方法而不必关心具体类型,可以确信抽象类的子类是一定实现了这些方法的。

接口

有一种极端的“抽象类”,它 只包含 抽象方法,这种东西可以写成 接口

interface Person {
    void run();
    String getName();
}

由于接口肯定都是抽象方法了,所以没必要用 abstract 修饰符。事实上它的方法都默认是 public abstract 。声明接口用 interface

某个类要去实现接口,要用 implements 关键字。

class Dog implements Animal {
    ...
}

Java中一个类只能继承自一个父类,通过接口则可以实现多重继承,一个类可以实现多个接口。(Python支持多重继承)

接口中还可以有一种 default 修饰符修饰的默认方法,这种方法可以有一个默认实现,具体实现的类可以 不必 覆写它。

有时候可能两个人都实现了一个名为 Person 的类,同时还想引用对方的类来使用。对于这种命名冲突的情况应该怎么办呢?

Java使用包 package 来解决命名冲突。在定义一个类时,把它的包名写在第一行。

下面是用IDE编写程序时自动创建的代码部分:

package com.company;

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

    }
}

与下面某人编写的同名 Main 类:

package harry;

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

    }
}

虽然这两个类同名了,但在运行时,这两个类会使用完整类名,它们的完整名分别是 com.company.Mainharry.Main

有时候要使用一个包中的类,一种写法是直接写完整类名,但那样就有点麻烦,我们可以和 Python 中一样使用 import 语句。

例如要使用 java.util 包中的 ArrayList

import java.util.ArrayList;

public class SingleImport {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
    }
}

这个包里还含有很多类,可以使用星号 *

import java.util.*;

这样表示把这个包里所有类都导入。

扫码关注:

Java笔记04:面向对象基础

原文  https://segmentfault.com/a/1190000020650047
正文到此结束
Loading...