继承
1、定义:
继承是指声明一些类,可以再进一步声明这些类的子类,而子类具有父类已经拥有的一些方法和属性,这跟现实中的父子关系是十分相似的,所以面向对象把这种机制称为继承
继承就是在现有类的基础上构建新类以满足新的要求
子类==派生类,子类只能有一个父类,父类可以有多个子类
注意:final类 方法 变量 不能被继承
2、声明:class 子类 extends 父类
比如:public class VipUser extends User
注意:子类构造函数是层层父类构造函数的调用,从最顶层的基类开始往下一层层的调用默认构造函数
public VipUser(){ super();// 调用父类的构造函数 System.out.println("子类构造器"); } public VipUser(String name){ // super("vip"+name);// 调用父类的构造函数 如果不调用的话 就会默认调用父类无参数构造器 System.out.println("子类有参数构造器");// 子类构造器内容 }
多态
指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
多态的实现:接口实现,继承父类进行方法重写,同一个类中进行方法重载。(接口下篇再讲)
3、方法重载和重写(覆盖)
覆写(重写):
父类的方法被子类重写,使用override ,如需使用父类中原有的方法,可使用super关键字
子类访问权限大于等于父类方法访问权限 并且重写方法只能重写父类非私有的方法
子类抛出异常小于等于父类方法抛出异常
子类返回值类型和父类相同
方法名相同参数类型相同
不同类,继承父类与父类有所不同
重载:同一个类中方法名相同参数类型不一致或者参数数量不一致
可以抛出不同的异常
可以有不同的访问修饰符
参数类型不一致或者参数数量不一致
方法名相同
同一个类中
4、绑定
前提是继承关系 子类并复写了父类的方法
子类和父类存在同一个方法,子类重写了父类的方法,程序运行时选择调用何种方法实现或者变量的操作叫做绑定
静态绑定:早期绑定,发生在编译时期
使用private或static或final修饰的变量或者方法
静态绑定使用类信息来完成
重载(Overload)的方法使用静态绑定完成
动态绑定:后期绑定,发生在运行时 1、有继承2、有重写3、父类引用指向子类对象
在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际类型调用其相应的方法,可以被子类重写的方法也称为虚方法
动态绑定则需要使用对象信息来完成
重写(Override)的方法则使用动态绑定完成
动态绑定使用方式:
父类 父类引用 =new 子类();
父类引用.method(); //该method方法在子类被覆写 此时调用的是子类的method
附:
public class TestVipUser { /** * @param args */ public static void main(String[] args) { /* * 动态绑定过程 * 创建父类引用 并指向子类对象 * 通过父类引用调用子类覆写的方法 */ User user=new VipUser(); user.speak(); /* * 静态绑定过程 * 根据参数选择protected void speak(String name){ * 还是 protected long speak(int age) */ User user1=new User(); user1.speak(11); } }
User
public class User { // 静态变量 public static String nationality = "china"; // 非静态变量 public String name; private int age; public User(){ System.out.println("父类构造器"); } // 带参数构造函数 public User(String name){ // this 的使用 this.name=name; System.out.println("父类有参数构造器"); } /* * 方法重载 * 同一类中 * 方法名一直 * 参数类型不一致或者参数数量不一致 */ public void speak(){ System.out.println("汉语"); } protected void speak(String name){ System.out.println(name); } protected void speak(String name,String age) throws RuntimeException{ //参数数量不一致 System.out.println(name+age); } protected long speak(int age) { // 参数类型不一致 System.out.println(age+""); return age; } // 不能被继承 public static final String getNation(){ return "china"; } // 静态方法 public static String getNationality() { return nationality; } public static void setNationality(String nationality) { User.nationality = nationality; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
VipUser
public class VipUser extends User{ private int vipCode; public VipUser(){ super();// 调用父类的构造函数 System.out.println("子类构造器"); } public VipUser(String name){ // super("vip"+name);// 调用父类的构造函数 如果不调用的话 就会默认调用父类无参数构造器 System.out.println("子类有参数构造器");// 子类构造器内容 } //覆写父类方法 参数列表必须完全与被重写的方法相同 @Override public void speak() { System.out.println("chinese"); }; //父类是protect 子类是public @Override public void speak(String name) { System.out.println(name); }; // 不能抛出其他异常 只能是父类异常的子类 ClassCastException是RuntimeException的子类 @Override protected void speak(String name, String age) throws ClassCastException { System.out.println(name+age); }; // 子类返回值类型和父类相同 @Override protected long speak(int name) { return name; }; public int getVipCode() { return vipCode; } public void setVipCode(int vipCode) { this.vipCode = vipCode; } }