Java中类与类之间的关系:
- 使用。即类A的方法操纵了类B(对象)的成员。
- 拥有。即类A中有类B类型的成员引用变量。
- 继承。
继承与隐藏:
继承也是一种访问。
当成员变量声明为默认类型时,包外的子类不能继承该成员变量。
protected与默认类型的区别在于,当成员变量被修饰为protected时,若访问该变量的类位于包外,则只有通过继承才能访问该变量,否则,即使通过子类类型的引用来访问,但也不能通过编译。
成员变量的隐藏会在子类具有与其父类的相同名称的成员变量时发生。其含义是指在子类中直接调用该成员变量时,将调用的是子类的而不是父类的。当然,父类的成员变量确实是被继承过来了的,只是被隐藏起来了的而已。所以,想要访问被隐藏起来了的父类的变量,得使用super关键字。
super与this同属预定义对象引用。
对象:
某个对象引用变量可以引用自身类型的对象实例或其子类及间接子类的对象。
类A继承于类B,故类A的对象引用变量可以引用类B的对象,但即使类A的对象引用指向的是类B的对象,当使用类A的对象引用调用与类B中相同名称的成员变量或方法时,系统仍然认的是类A的对象引用而不是其所指向的对象。否则,需进行强制类型转换。
强制类型转换转的只是引用类型,对真正指向的对象是不会干预的。在这句话中,还可以引出另外一个意思,即对于编译而言,只要被转换的引用类型与转换后的目标类型是派生或被派生关系,则编译通过;同时,编译系统并不知道引用所指向的具体对象是什么,其只能根据引用类型来判断转换有没有希望。在运行时才能知道是否能进行引用的强制类型转换。
引用赋值可以直接将子类引用赋给父类引用;若需将父类引用赋给;子类引用,则必须进行强制类型转换。
对于引用的比较,Java中有相应的要求:
- 相同类型的引用可以比较;
- 不同类型的引用要进行比较,其中的类型要具有派生关系;
- 引用的比较是比较两个引用是否指向同一个对象。
方法的重写:
当父类的引用指向子类对象时,若访问被重写的方法,则将访问的是被重新定义的子类中的方法(这点与访问类的属性不同)。
若想构成重写,子类中的方法名与参数列表必须完全相同(即签名要一致),此时,要遵循以下规则:
- 返回类型要兼容;
- 访问级别的限制一定不能比被重写方法的窄,可以比被重写的方法宽;
- 不能重写被表示为final的方法。
重写与继承的关系:
若父类的方法为private的,根本不能被子类继承,既然不能被继承,也就可能形成重写了,更谈不上要遵循重写中的规则之类的了。
静态方法可以被继承,但不能被重写:
- 非静态方法会试图重写静态方法时,编译报错;
- 静态方法的隐藏。父类和子类都有相同签名的static方法,但用父类引用调用的是父类方法,用子类引用调用的是子类的方法,与对象无关。
- 当用子类引用调用子类本身没有的,而父类有而且可继承(即非private的)的方法时,调用从父类继承的方法。
可以在重写父类的方法时通过super引用相应的父类的方法来扩展子类中重写了的方法的功能。
隐藏是根据引用的类型来进行调用的(调用static方法和成员变量),重写是根据对象的类型来进行调用的。
上述说法都是基于面向对象中一个非常重要的原理——替代性,即子类能替代父类。
方法的重载:
只有在同一个类里才有方法重载的说法。重载中的对象引用参数是面向引用类型的,而与其所指向的具体对象无关。
final与继承:
final的类无法继承,故无法重写该类的方法;final的方法无法被重写,只能被继承。
abstract与继承:
抽象类永远不能被实例化,它的主要用途是用于继承和扩展。
抽象方法只有方法声明,没有方法体(即没有花括号)。
抽象类中可以有非抽象方法,这种方法往往是抽象类所有未来子类都具有的,且不会因为子类的不同而具体实现不同的方法。