关键字: 继承 重写 Super Object #一、继承
引入 *继承:根据已有类 派生出新类的技术。 子类 可以 继承父类的 所有功能,而且可以增加自己独特的功能。 单一继承。(只能有一个父类) 优点: 1. 代码重用; 2.方便维护。(高耦合) 语法:
示例: 父类Teacher 子类 JavaTeacher 新建一个类TestTeacher,在类中创建子类JavaTeacher的对象,那么对象可以调用 JavaTeacher 子类 和 父类 Teacher中,含有变量和方法。(右上方中,调用父类中的givelesson 方法) 注意: 1。父类中私有private的成员,不能继承;(因为private 的变量,可见度是本类中) 2.父类和子类不在同一个程序包,父类中使用默认访问权限的成员不能继承。(例如 string name ; 默认的访问权限,可见度是本包) 3.构造方法不能继承。(构造是用来初始化成员的,父类有父类的构造,子类有子类的构造,不能继承但是可调用)
里氏替换原则 *子类 是 父类 ,子类 对象 可以 完全 替换掉 父类对象 ,程序没有任何的影响。 points: 子类是必须 完全继承 父类所有的东西(变量/特征,方法/技能) 如上图中的案例,父类 鸟类中 有会飞的技能 ,鸵鸟类 不能继承父类 ,因为一旦 鸵鸟继承鸟类过来,就代表鸵鸟会飞飞飞飞 ,哈哈哈,鸵鸟又飞不了,所以不能继承。 (后面会有interface 接口,接口更像是一个个小的技能点,你可以选用(实现)自己喜欢的技能点(接口)) #二、方法重写 方法重写的作用,干啥用? 什么情况下要重写: 1. 子类 修改了父类的功能;(修改了构造方法中的 技能点) 2.子类扩展了父类的功能。(拓展了构造方法中的 技能点) 父类 : class 手机{ 来电显示(){ 电话号; } } class 子类手机{ 来电显示(){ 电话号; 人名; 照片; 归属地。 } }
方法重写 几大原则: 1.在子类中; 2.子类 中的实例成员方法;(属于对象) 3.方法名相同; 4.参数列表相同; 父类擦除后 与 子类相同就可以。(如代码中的第12行) 5.返回值类型相同; 引用类型: 子类的返回值类型 可以是父类的子类型。
6.访问权限 不能比父类更严格(低); 7.异常范围 不能比父类更大。 案例: class Base{ // 字节码文件中会擦除泛型信息 public Base f(ArrayList arr) { Base base = new Base(); return base; // return new Base(); } } class Sub extends Base{ // 注解 @Override public Sub f(ArrayList arr) { return new Sub(); } } public class TestOverrid1 { public static void main(String[] args) { // TODO Auto-generated method stub } } #三、super super: 调用父类的成员。 属性,方法,构造;
区分 父类和子类同名的方法封装属性private: 提供公共的访问方式: 1) getter ,setter
构造 创建子类对象 ,必须 先调用父类构造 然后再执行子类构造代码。 子类构造中 没有显示的写 super() 或 this() ,那么编译器 会自动 分配 super()调用父类构造。 在测试类中,变量的传递过程: 测试类中的变量------->子类 javaTeacher 构造方法中的string name------>super (name)----->父类中构造方法中的参数String name----->构造方法中 this.name=name-------> 父类中 private string name 调用父类构造: super() 位置: 1.子类 构造中; 2. 子类构造的第一行代码处。特殊: 父类中 只有 一个 带参数的构造,那么子类中 必须显示定义带参构造 在 构造中 显示 调用父类 带参构造 super(参数);
四、继承传递性 子类可以继承直接父类的功能 ,也可以 继承间接父类的功能。 使用super(),一直调用父类的相关功能就可以了。一般是是super() or super(参数),调用构造方法,或者调用父类中的变量特征。 创建任何对象 , 调用父类构造时 ,一直调用到 Object() 的构造位置。 // 间接父类 class Grandpa{
public Grandpa() { super();// Object () } String name; public void eat() { System.out.println("吃粥"); }} // 直接父类 class Father extends Grandpa{
public Father() { super(); } int age; public void eat() { System.out.println("吃面条"); }} // 子类 class Son extends Father{
public Son() { super(); } String tattoo; public void eat() { System.out.println("吃米饭"); System.out.println(name); } public void f() { super.eat(); }} public class TestGrandpa { public static void main(String[] args) { Son guojing = new Son(); guojing.f(); // System.out.println(guojing.tattoo); // System.out.println(guojing.age); // System.out.println(guojing.name); } } 五、Object类 所有类的父类(超类) 。
1. 构造 Object() : 为 所有的子类 创建对象设计的。 2.clone() : 克隆对象,复制对象
int [] arr = {1,2,3}; int [] arr1 = arr.clone();3.finalize() : 垃圾回收器 释放对象 之前 会 调用 finalize()方法 来 释放(清理) 资源。
class Employee{ @Override protected void finalize() throws Throwable { // 释放资源 System.out.println(“this---->” + this); }
} public class TestEmployee { public static void main(String[] args) {
Employee guojing = new Employee(); System.out.println(guojing);// 15db9742 guojing = null; // 强制垃圾回收(通知垃圾回收器) System.gc(); }} 4. equals(); 比较两个对象的地址是否相等。 int n = 23; int n1 = 45; Student guojing = new Stuent(); Student yangkang = new Studnet(); guojing == yangkang // 判断的是地址 Object类的源码: public boolean equals(Object obj) { return (this == obj);// 比较地址 }
5.finalize //注意: 强制垃圾回收------通知系统垃圾回收(一般系统的垃圾回收,是当创建对象,发现内存不够用了,然后才会进行垃圾回收) 在垃圾回收对象,释放对象之前,会调用finalize( )方法。
6.hashCode(): hash :哈希值,散列值 ,是 一个 int数字 ,是 对象 的唯一标识。(相当于 人------身份证号)
用 这是 哈希值 int 唯一 表示一个对象;
用 哈希值 作为 内存中 对象 存储的位置;
(hash值 ,默认的就是源码中的地址值,当然hash值可以更改的,如果里面的hash算法,自己更改了重新定义了,那hash值就改变了)
哈希值 是 通过 hashCode() 中的 算法算出来的。 class Student2{ private int no; private String name; public Student2(int no, String name) { super(); this.no = no; this.name = name; } public int getNo() { return no; } public String getName() { return name; } @Override public String toString() { return no + “,” + name; } // @Override // public int hashCode() { // // return no ; // } @Override public int hashCode() {
int result = 1; result = 31 * result + no; return result;}
} public class TestStudent2 { public static void main(String[] args) {
Student2 guojing = new Student2(11, "郭靖"); System.out.println(guojing.hashCode());// 366712642 Student2 yangkang = new Student2(22, "杨康"); System.out.println(yangkang.hashCode());// 1829164700 }}
7.toString();对象的字符串表示形式。 用 println() print() 输出对象名称的 时候 会隐式 调用toString();
public String toString() { return getClass().getName() + “@” + Integer.toHexString(hashCode()); } class Student1{ private int no; private String name; public Student1(int no, String name) { super(); this.no = no; this.name = name; } public int getNo() { return no; } public String getName() { return name; } /* public String show() { return no + “,” + name; }*/ @Override public String toString() { return no + “,” + name; }
} public class TestStudent1 { public static void main(String[] args) { Student1 guojing = new Student1(11, “郭靖”); // new Student1(11, “郭靖”)对象的 类型 @ 对象的hash值 //day1202.Student1@15db9742 System.out.println(guojing.toString()); // System.out.println(guojing.getClass().getName());// day1202.Student1 // System.out.println(guojing.hashCode());// 366712642 int 10 // System.out.println(Integer.toHexString(guojing.hashCode()));// 15db9742 16进制
}}