背景
有的时候客观事物之间就存在一些关联关系, 那么在表示成类和对象的时候也会存在一定的关联
// Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "吃东西啦" + food);
}
}
// Cat.java
class Cat {
public String name;
public Cat(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "吃东西啦" + food);
}
}
// Bird.java
class Bird {
public String name;
public Bird(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "吃东西啦" + food);
}
public void fly() {
System.out.println(this.name + "我要飞啦 ");
}
}
这个代码我们发现其中存在了大量的冗余代码
.
仔细分析
,
我们发现
Animal
和
Cat
以及
Bird
这几个类中存在一些相同的地方,类也有一定的关联关系。
●
这三个类都具备一个相同的 eat
方法
,
而且行为是完全一样的
.
●
这三个类都具备一个相同的 name
属性
,
而且意义是完全一样的
.
●
从逻辑上讲, Cat
和
Bird
都是一种
Animal (is - a
语义
)
二、语法规则
class 子类 extends 父类 {}
- 使用 extends 指定父类.
- Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承).
- 子类会继承父类的所有 public 的字段和方法.
- 对于父类的 private 的字段和方法, 子类中是无法访问的.
- 子类的实例中, 也包含着父类的实例. 可以使用 super 关键字得到父类实例的引用.
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
class Dog extends Animal{
public Dog (String name){
super(name);
}
}
//super(name) 调用父类带有一个参数的构造方法
super
- 是对父类对象的引用
- 不能出现在静态方法当中
- 调用父类的构造方法,必须放在第一行
三、访问权限
在上述代码中,如果将父类的字段设置为private,那么子类就不能访问了,但是之前的public又违背了“封装”的初衷。那么此时protected关键字就很完美的解决了这个问题。
①对于类的调用者来说,protected修饰的字段和方法是不能被访问的
②对于类的子类和同一个包的其他类来说,protected修饰的字段和方法是可以访问的
如果一个类不想被继承 我们可以用final修饰
final int a = 10;//这样常量就不能被修改了
final class A //代表整个类不能被继承
四、继承中的代码块
在继承关系中,代码块的执行顺序是:
父类静态代码块 -> 子类静态代码块 -> 父类实例代码块 -> 子类实例代码块 -> 方法
接下来请看代码
//动物类
class Animal{
public String name;
//静态代码块
static {
System.out.println("Animal static");
}
//实例代码块
{
System.out.println("Animal instantiation");
}
public Animal(String name){
this.name=name;
}
public void eat(){
System.out.println(this.name+"eat");
}
}
//鸟类
class Bird extends Animal{
//静态代码块
static {
System.out.println("Bird static");
}
//实例代码块
{
System.out.println("Bird instantiation");
}
public Bird(String name) {
super(name);
}
public void fly(){
System.out.println(this.name+"fly");
}
}
public class Test{
public static void main(String[] args) {
Bird bird=new Bird("小可爱");
bird.eat();
bird.fly();
}
}
//打印结果
Animal static
Bird static
Animal instantiation
Bird instantiation
小可爱eat
小可爱fly
要注意静态代码块只初始化一次