继承用来解决成员变量或方法大量重复的问题,将重复代码抽取到父类中
//父类A
public class A{
int a; //缺省(包权限),仅能在本包中使用
private int b; //私有,仅能在本类中使用
public int c; //公有,在任何地方都可使用
protected int d; //保护类,缺省+不同包子类
public String toString(){...}
}
//假设有类B继承类A
public class B extends A{
int a; //变量的隐藏
public String toString(){...} //方法的重载(重写)
}
//编译器会一直上溯到最顶端的超类,执行该类构造方法,然后依次执行各子类构造函数
class A{
public A(){
System.out.println("调用了A类的构造方法");
}
}
class B extends A{
public B(){
System.out.println("调用了B类的构造方法");
}
}
public class C extends B {
public C(){
System.out.println("调用了C类的构造方法");
}
public static void main(String args[]) {
C c=new C();
}
}
/*
程序运行结果:
调用了A类的构造方法
调用了B类的构造方法
调用了C类的构造方法
/*
表示对子类对父类的引用
如果在子类中未显式调用父类构造方法,则编译器会默认使用super()自动调用父类的无参构造方法(默认/覆盖),假若父类没有提供无参构造方法,编译时将出错
//引用父类的成员(需要相应的访问权限):
super.变量
super.方法([参数表])
//在子类构造方法中调用父类的构造方法:
super([参数表]); //必须放在构造方法的第一行位置上
用于判断一个类是否实现接口或判断一个对象是否属于一个类
//instanceof运算符格式
对象 instanceof 类或接口
//结果:true或false
同一个引用类型,使用不同的示例而执行不同的结果
//子类转父类:向上转型
子类对象句柄 = (子类名) 父类对象;//需要强制转换,损失精度
//父类转子类:向下转型
父类对象句柄 = 子类对象;
静态多态主要是指方法重载,与是否发生与继承没有必然联系
//多态性的例子(续)
public class AnimalTest {
public static void main(String args[]){
Animal am=new Animal();
am.roar();
am=new Dog();
am.roar();
am=new Cat();
am.roar();
}
}
/*程序运行结果:
动物:...
狗:汪,汪,汪,...
猫:喵,喵,喵,...*/
根据对象的赋值规则,可以把子类对象赋给父类对象名
父类对象名.roar()去调用时,能够根据子类对象的不同,得到不同的结果,这就是多态性。
抽象类指不能实例化的类,其可以包含或不包含抽象方法
抽象类生来就是为了被子类继承
抽象类 | 具体类 |
---|---|
用于划分具体类 | 用于表示真实世界的对象 |
不能实例化 | 可以实例化 |
可定义未提供实现的抽象方法 | 不能定义未提供实现的抽象方法 |
可为自己的部分方法提供实现 | 为所有方法提供实现 |
//抽象类的定义格式:
[访问权限] abstract class 类名{……}
//如
abstract class Shape {……}
//抽象方法的定义格式:
[访问权限] abstract 返回类型 方法名([参数表]);//无方法体
//抽象方法举例:
public abstract double getArea();
public abstract double getPerimeter();
当一个类中包含有抽象方法时,该类一定要声明为抽象类
子类继承抽象类时,必须实现该抽象类中的所有抽象方法
当类实现了一个接口,但并没有实现该接口的所有方法时,该类必须声明为抽象类,否则出错
抽象方法无方法体,在缺省情况下默认为public
抽象方法不能被private、final或static修饰
接口可以实现不相关类的相同行为,只关注功能,不关注具体实现
一个类可以继承多个接口
接口中的方法都是抽象方法,成员变量都为静态常量
//接口的定义——interface关键字
[权限修饰符] interface 接口名 [extends 父接口列表]{
//抽象方法和静态常量
}
//如
public interface Runner {
int id = 1;
public void start();//无方法体
public void run();
public void stop();
}
//接口的实现——implements关键字
[修饰符] class 类名 [extends 父类] implements 接口1[,接口2,…]{
…… //包含对接口的所有方法的实现
}
//接口实现示例
public class Person implements Runner{
public void start() {
// 准备工作:弯腰、蹬腿、咬牙、瞪眼
// 开跑
}
}
//接口的继承——允许一个接口用extends继承另一个接口
接口名 extends 父接口1[,父接口2,…]{
…… //新增的抽象方法或静态常量
}