1. 继承
类的继承方法为:
class masterClass{
private Type arg1;
private Type arg1;
public masterClass(Type arg1, Type arg2){
this.arg1 = arg1;
this.arg2 = arg2;
}
}
// 使用关键字 extends 继承
class slaveClass extends masterClass{
public slaveClass(Type arg1, Type arg2){
super(arg1, arg2);
}
}
extends
- 一个子类只能拥有一个父类, extends 可以继承一个类
super
和 this
关键字
- 可以通过 super 关键字来实现对父类成员的访问,用来引用当前对象的父类
- this 指向自己的引用
构造器
- 子类是不继承父类的构造器的,它只是调用(隐式或显式)
- 如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表;
- 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
1.1 举例
首先看一个具体的例子:
// fileName:Test.java
class Animal{
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void getInfo() {
System.out.println("Name: " + this.name);
System.out.println("Age: " + this.age);
}
}
class Cat extends Animal{
public Cat(String name, int age) {
super(name, age);
// super.getInfo();
}
}
public class Test {
public static void main(String[] args) {
Cat tom = new Cat("Tom", 3);
tom.getInfo();
}
}
上面的代码中定义了3个类:Animal、Cat 和 Test
Animal
:父类,定义了动物的基本属性
- private 属性只有类的方法可以访问和修改
- public 方法可以被子类继承调用
Cat
:子类,继承了 Animal
- 子类拥有父类非 private 的属性、方法(private 属性不能被继承,因为不能通过 子类的方法来直接访问 private 属性,只能通过调用父类的 public 函数来访问父类的 private 属性)
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
- Java 支持单继承和多重继承,不支持多继承
Test
:public 类,用来测试
- Test 类创建了 Cat 的对象,同通过对象调用了父类 Animal 的方法
- 一个 Java 文件中可以定义多个类
- 但是最多只有一个类被 public 修饰,并且这个类的类名与文件名必须相同
1.2 关键字
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类;
使用 implements 关键字可以变相的使 Java 具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口;
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
final 关键字声明类可以把类定义为不能继承的
2. Override & Overload
2.1 重写 Override
方法重写 是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写;
class Animal{
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void getInfo() {
System.out.println("Name: " + this.name);
System.out.println("Age: " + this.age);
}
}
class Cat extends Animal{
private String color;
public Cat(String name, int age, String color) {
super(name, age);
this.color = color;
}
public void getInfo() {
super.getInfo();
System.out.println("Color: " + this.color);
}
}
public class Test {
public static void main(String[] args) {
Animal ruby = new Animal("Ruby", 2);
ruby.getInfo();
Cat tom = new Cat("Tom", 3, "Brown");
tom.getInfo();
}
}
上面的代码中,Cat
重载了 Animal
的方法 getINfo()
,使用 super
关键字调用了父类的方法,输出结果为:
Name: Ruby
Age: 2
Name: Tom
Age: 3
Color: Brown
方法重写规则
-
返回值和形参都不能改变
- 访问权限不能比父类中被重写的方法的访问权限更低(即可以降低限制)
- 声明为 final 或 static 的方法不能被重写
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法
2.2 重载 Overload
方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)
规则
- 被重载的方法必须改变参数列表(参数个数或类型不一样)
- 被重载的方法可以改变返回类型
- 被重载的方法可以改变访问修饰符
- 被重载的方法可以声明新的或更广的检查异常
方法重写 是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写;
方法重载 是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载;
多态 是同一个行为具有多个不同表现形式或形态的能力,继承、方法的重写重载体现了多态。
3. 封装
- 修改属性的可见性来限制对属性的访问,一般限制为private;
- 对每个值属性提供对外的公共方法访问,用于对私有属性的访问,它们是外部类访问该类成员变量的入口;
class Animal{
// 私有属性
private String kind;
private String color;
// 接口
public Animal(String kind, String color) {
this.kind = kind;
this.color = color;
}
public void getInfo() {
System.out.println("kind: " + kind + "\n" + "color: " + color);
}
}
4. 枚举类型
枚举类型是一个特殊的类,用 enum
来声明
如下定义一个季节的枚举类,在其中枚举类成员:
enum Season{
SPRING, SUMMER, AUTUMN, WINTER;
public void getInfo() {
System.out.println("Four seasons in a year.");
}
}
下面访问一个枚举类型的所有值:
values()
返回枚举类中所有的值(返回值为数组类型)
enum Season{
SPRING, SUMMER, AUTUMN, WINTER;
}
public class AbstractClassTest {
public static void main(String[] args) {
Season s = Season.AUTUMN;
System.out.println(s);
System.out.println(s.getClass());
for (Season tmp : Season.values()) {
System.out.print(tmp + " ");
}
}
}
5. package
5.1 package 作用
- 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
- 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
- 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
5.2 创建和使用包
1. 包的定义
在一个包里面添加类的方法如下:
package 包名; //多级包用.分开
pulic class Dolphin{
}
注意:
(1) 包名要小写;
(2) 一个源文件只有一个 public 类;
(3) package语句必须在文件中的第一条有效语句
2. 包的目录结构
如图,在当前目录 src
中创建一个类和一个 package , package 包含了两个类 Cat 和 Dog
下面的代码是 Cat 类定义(Dog 类的定义类似)
// src/mypackage/Cat.java
package animals;
public class Cat {
private String color;
private String name;
public Cat(String name, String color) {
this.color = color;
this.name = name;
}
public void printInfo() {
System.out.println(name + " is a " + color + " cat.");
}
}
3. 包的使用
下面是带有主函数的类:
import animals.Cat;
import animals.Dog;
public class PackageTest {
public static void main(String[] args) {
Cat tom = new Cat("Tom", "brown");
tom.printInfo();
Dog lucy = new Dog("Lucy", "red");
lucy.printInfo();
}
}
使用包的时候在源文件最上方声明,也可以一次性包含包内所有的类:
import mypackage.*;
输出的结果为:
Tom is a brown cat.
Lucy is a red dog.
5.3 编译运行
// 单独一个文件时
javac A.java
// 包含包时(*.java代表当前目录下的所有源文件)
javac -d . *.java