目录
继承:
一、继承主要表示概念层上的 is-a 的关系
二、什么是继承:
三、语法
四、继承方式:
五、访问权限
六、构造方法
七、父类的属性和方法的访问
八、重载和重写(前提是子类是有权限的)
九、执行顺序
多态:
一、多态实际上是一种向上转型
二、包含一切的隐式赋值
三、怎么访问
四、小结
继承:
一、继承主要表示概念层上的 is-a 的关系
二、什么是继承:
举个例子: 类A(动物) -> 类B(猫) --类A 类B 之间有层级关系
类B 继承 类A 、类B 派生于 类A 、类B 扩展于 类A
类A : 父类 基类 超类
类B : 子类 派生类
三、语法
父类在语法上没有任何要求;子类 extends 父类 { ... }
四、继承方式:
一个类 有且只有一个父类 classA{ ... } 隐含继承自 Object类
五、访问权限
public > protected > 什么都不写 > private
如果父类的属性、方法权限是 private :子类没有权限使用;什么都不写:如果子类和父类是同一个包下的类,就有权限;protected:子类 和 父类在同一个包下就有权限;public 子类有权限
六、构造方法
在子类的构造方法中,必须显式或者隐式调用父类的构造方法(用super);
public class Derived extends Base {
//子类的构造方法中必须先调用父类的构造方法(通过super关键字调用)
//当子类和父类都是无参构造方法时,可以省略
public Derived(int a) {
super(a);
}
public Derived(String b) {
super(b);
}
}
当父类和子类都是无参构造方法时,super()可以省略
例外:如果父类有无参构造方法,子类的构造方法中,隐含着调用了父类的构造方法
七、父类的属性和方法的访问
通过 super 可以明确访问父类中的属性和方法(有访问权限的前提下)
Base { a;method(); }
D1 extends Base{
a; method();
m2(){ a; this.a; super.a; super.method; }
}蓝色调用自己的 红色调用父类的
没有名称歧义时,直接通过 this 也可以
八、重载和重写(前提是子类是有权限的)
public class B{
int add(int a, int b){ ... }
}
public class D extends B{
double add(double a,double b){ ... } //与class B 中的add互为重载关系 (overload)
int add(int a,int b){ ... } //与class B 中的add互为重写/覆写关系 (override)
}
@Override 明确该方法试图重写父类方法
MyRandom extends Random{
@Override //注解
public int nextLnt(){ ... }
}
九、执行顺序
1.使用类之前,必须进行类的加载(类的初始化代码执行顺序)
静态代码块 和 静态属性 按照代码书写顺序执行
2.对象实例时,必须进行对象的构造过程(隐含着,可能出现类的加载)
构造代码块 和 属性 按照代码书写顺序执行
构造方法执行
3.子类的加载之前,必须保证父类先加载完成(用到子类,隐含着用到父类)
4.子类的的对象构造之前,先把父类的对象构造完
多态:
一、多态实际上是一种向上转型
上级的引用可以指向下级的对象
(上级) Obiect -> Ancestor -> Grandpa -> Parent -> A (下级)
A a = new A(); Parent p = new A(); Grandpa g = new A(); Ancestor a = new A();
Object o = new A();
二、包含一切的隐式赋值
①public void method(Ancestor an) { ... }
method( new A() ); Ancestor an = new A();
②public Ancestor method() {
A a = new A();
return a; Ancestor an = a;
}
③public A method() { ... }
Ancestor an = method(); Ancestor an = new A();
三、怎么访问
当存在普通方法重写时,即使在父类方法中调用 this.hello(),执行的哪个方法,和对象的类型有关(由于对象是D的对象,执行的是D对象的hello;)
public class B {
public void method(){
System.out.println("我是父类的 method");
this.hello();
}
public void hello(){
System.out.println("我是父类的 hello");
}
}
public class D extends B {
@Override
public void hello() {
System.out.println("我是子类的 hello");
}
}
public class Use {
public static void main(String[] args) {
D d = new D();
d.method();
}
}
执行结果为:
举个栗子:
B { a(); b(); }
D extends B{ b(); c(); d(); }
D d = new D(); d.a(); d.b(); d.c(); d.d();
B b = new B(); b.a(); b.b();执行的是D类中的b
能执行哪些功能(属性、方法),看引用类型;实际执行的是哪个功能,看对象类型
四、小结
class Animal { public int a; public void method(){ ... } }
class Dog extends Animal { public int b; public void otherMethod(){ ... };
public void method(){ ...重写了父类的方法... }
1. Animal a = new Dog(); 任何对象都可以被其上层引用指向(向上转型),向上转型是自然的;
2.①能访问哪些属性,根据引用类型决定:a.a 对的; a.method() 对的; a.b 错的; a.otherMethod(); 错的;
②真正执行的方法,由对象类型决定:a.method(); 真正执行的是Dog中的 method 方法,由于a 目前指向的对象是Dog 类型
3.某些情况需要调用子类中的独有的某个方法时,必须向下转型,向下转型是不自然的,有风险的,例如:Dog d = (Dog)a;
4.判断 -> Animal instanceof Dog -> 是 true 还是 false
5.如果没有判断,有可能会发生异常ClassCastException 发生错误转换
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)