类的继承
继承规则
- Java只允许单继承,每一个类只能有一个父类,每一个类可以有多个子类。
- 子类继承(拥有)父类所有方法(未必可以调用,private关键字)和属性
子类实例化(new 对象)过程 - 子类实例化时,先实例化父类,再实例化子类
- 先调用父类的构造器,再调用子类的构造器
调用构造方法
在构造方法中,调用构造方法可以使用this和super关键字。
- super()
调用父类构造器,只能出现在子类中,且出现在第一行,括号内的参数列表决定了调用哪个构造器。 - this()
调用子类构造器,出现在第一行。
/**
*
*/
package test2;
/**
* @author xiaochen
*
*/
public class Animal {
String name;
int age;
public Animal() {
}
public Animal(String string) {
System.out.println("会叫");
}
public void test() {
System.out.println("hh");
}
}
/**
*
*/
package test2;
/**
* @author xiaochen
*
*/
public class Dog extends Animal {
String zl;
public Dog() {
}
public Dog(String string) {
super(string);
System.out.println("汪汪汪");
this.test();
super.test();
}
public void test() {
System.out.println("hhh");
}
}
结论:无论是调用父类构造器,还是子类构造器,最终都会找到最顶级的父类自上而下实例化。中间环节有一个构造器没有找到,这个子类就无法完成实例化。
权限修饰符
权限修饰符类型包括:public > protected > default > private
图解权限修饰符:
封装机制:对成员访问权限的任何控制都称为封装机制。
protect 权限修饰符
下面两子类与父类的代码是在不同包的
/**
*
*/
package test2;
/**
* @author xiaochen
*
*/
public class Super {
protected void show() {
System.out.println("父类受保护方法");
}
}
/**
*
*/
package test;
import test2.Super;
/**
* @author xiaochen
* */
public class Sub extends Super {
/*public void test() {
//子类可以访问父类的受保护方法
show();
Sub sub = new Sub();
//能使用子类对象调用继承的受保护方法
sub.show();
}*/
//这是错误代码
public void test() {
Super super = new Super();
//不能用父类对象调用受保护方法
super.show();
}
}
protected:受保护的,除了可被类自身及与其在同一个包中的代码访问外,还可以在一个类中通过对象引用来访问,前提是这些对象引用至少应该具有与该成员所在的类相同的类型,也即是这些引用具有该成员所在类的类型或是其一子类型。
方法的覆盖override(重写 rewrite)
方法覆盖规则
- 子类中覆盖的方法在父类中也有
- 同名,同参数列表,同返回值类型
- 子类覆盖方法访问权限要不小于父类中被覆盖方法权限。
abstract和final
abstract关键字定义抽象方法和抽象类,抽象方法只有声明,没有实现方法,没有方法体,
抽象方法需要子类重写该方法,因此不能使用private和final修饰。
抽象类是抽象方法和非抽象方法的集合,可以有抽象类中全为抽象方法或全为非抽象方法的情况存在。
- 抽象类不能被实例化
- 抽象方法必须在其子类中被实现,否则子类只能声明为abstract
- 抽象方法不能为static
一个类必须声明为抽象类 - 当一个类的一个或多个方法是抽象方法时
- 当类是一个 抽象类的子类,并且没有实现父类的所有抽象方法,即只实现部分
- 当一个类实现一个接口,并且不能为全部抽象方法都提供实现时
接口(interface)
- 接口中只包含常量和抽象方法,而没有变量和方法的实现
- 接口对类来说是一套规范,是一套行为协议
- 接口不是一个类,没有构造器,不能被实例化
- 接口使用interface关键字来定义,而不是class
- 接口默认:
- 常量:public static final;
- 抽象方法: public abstract
类实现接口——implements
- 为了使用一个接口,你要编写实现接口的类
- 如果一个类要实现一个接口,那么这个类就必须实现接口中所有抽象方法。否则这个类只能声明为抽象类
- 多个无关的类可以实现一个接口,一个类可以实现多个无关的接口
- 一个类可以在继承一个父类的同时,实现一个或多个接口
接口和类的关系
- 用接口可以实现混合类型(主类型,副类型),在Java 中可以通过接口分出主次类型
- 主类型使用继承,副类型使用接口实现
- 接口可以使方法的定义和实现相分离,降低模块间或系统间的耦合性
接口和抽象类的对比
- 接口不能含有非抽象方法,而抽象类可以。
- 类可以实现多个接口,但父类只能有一个
- 接口和接口可以多继承
final常用方式
- 常量设置为静态,多个实例化对象公用。
- 赋值后不能改变
- 命名规范:所有字母大写、单词间不能下划线
引用数据类型的转换
向上塑型(Upcasting)
- 子类转换为父类,自动转换。
- 子类会丢失自己的方法(无法调用)和属性,仅可以使用父类的方法和属性
- 示例
class Animal{}class Cat extends Animal{} Cat a = new Cat( );Animal c = a;
猫是动物类。猫为子类,动物类为父类。
向下塑性(Downcasting) - 父类转化为子类,强制转换。
- 向上塑型后才能向下塑型,不允许直接向下塑型
class Animal{}class Cat extends Animal{} Animal a = new Cat(); cat c = (Cat) a;
instanceof运算符
通过instanceof运算符判断经过向上塑型后是哪一个子类
- 使用instanceof运算符
- 判断一个对象是否属于一个类。
object instanceof class - 判断一个类是否实现了某个接口
object instanceof interface - 返回值都是Boolean类型值
多态(Polymorphism)
判断多态条件
- 要有继承或实现
- 要有重写
- 父类引用指向子类对象