关键字: 继承 重写 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进制
}
}