I. 继承(extends)
1. B类继承A类,则称A类为超类(superclass)、父类、基类,B类称为子类(subclass)、派生类、扩展类。
class A { }
class B extends A { }
2. java中没有多继承,即不会出现这样的代码:class C extends A, B { }
但是有简介继承 class C extends B { }; class B extends A { }
3. java中规定,子类继承父类,除构造方法不能继承之外,剩下的都可以继承。但是私有的属性无法在子类中直接访问。但可以间接访问,比如调用继承来的getter方法。
4. 继承有缺点:耦合度太高了,一旦修改父类,子类就会受牵连。
5. Object类的一些方法:
1) 多看jdk的源代码,位置:D:\jdk_Java\lib\src;
Object类在 D:\jdk_Java\lib\src\java.base\java\lang (注:String类等很多很重要的类也在lang里面)
2) 当源码当中一个方法以“ ; ” 结尾,并且修饰符列表中有“native”关键字,表示底层调用C++编写的dll程序 (dll动态链接库文件) 。
3) equals方法
4) toString方法:当System.out.println()内是一个引用时,println()方法会默认执行这个引用的toString方法,并返回toString方法的返回值(toString方法默认返回"类名"+"@"+"一个表示什么来着的16进制数")。可以理解为把对象转换成字符串的形式。
II. 重载(overload)
1. 解释:在一个类中,如果功能相似,建议将名字定义成一样,这样代码美观,并且方便编程。
2. 构成方法重载的条件:
1) 在同一个类中,或者子类中的方法重载了父类中的(子类有父类中的一切方法,所以也是在同一个类中)
2) 方法名相同
3) 参数列表不同 (个数、顺序、类型)
III. 重写(覆盖override)
1. 解释:子类继承父类时,有些方法可能不需要改进,还有些方法可能已经无法满足子类的业务需求,必须改进。
2. 构成方法重写的条件:
1) 两个类必须有继承关系
2) 重写后的方法和原方法具有相同的返回值类型、相同的方法名、相同的形式参数列表
3) 访问权限不能更低,可以更高 (只能由protected变成public,不能反过来...)
4) 重写之后的方法不能比原方法抛出更多的异常,可以抛出更少的
3. 注意事项:
1) 方法覆盖只针对于方法,和属性无关
2) 私有方法无法覆盖
3) 构造方法不能被继承,所以也不能被覆盖
4) 方法覆盖只是针对于实例方法,静态方法覆盖没有意义
5) 覆盖时最好把父类方法复制粘贴
6) 重写的方法返回值可以比之前小,但不能大(小是指子类)
4. 案例:
1) 典型案例1:
package Override;
public class OverrideTest01 {
public static void main(String[] args) {
//创建鸟对象
Bird b = new Bird();
//鸟移动:飞翔
b.move();
//创建猫对象
Cat c = new Cat();
//猫移动:走猫步
c.move();
}
}
class Animal{
public void move() {
System.out.println("动物在移动!");
}
}
class Bird extends Animal{
//对move方法进行方法重写/覆盖/override
//最好将父类中的方法原封不动的复制过来(不建议手动编写)
public void move() {
System.out.println("鸟儿在飞翔!");
}
}
class Cat extends Animal{
public void move() {
System.out.println("猫在走猫步!");
}
}
2) 典型案例2:
package Override;
//方法覆盖经典案例
public class OverrideTest02 {
public static void main(String[] args) {
ChinaPeople c = new ChinaPeople();
//c没有有参构造方法可以用
c.setName("李四");
c.speak();
AmericPeople a = new AmericPeople();
a.setName("Jack");
a.speak();
}
}
class People{
private String name;
public People() {}
public People(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//人都会说话
public void speak() {
System.out.println(name+"......");
}
}
//中国人
class ChinaPeople extends People{
/*public ChinaPeople() {
super("张三");
}*/
//子类不能继承父类的构造方法,所以这里只有个默认的无参构造方法
public void speak() {
System.out.println(this.getName()+"正在说汉语");
//调用实例方法时要用引用.
//调用所处环境有引用this 直接用this,没有(静态环境),现new一个
//这里是非静态环境,直接用this.
}
}
class AmericPeople extends People{
/*public AmericPeople() {
super("Mary");
}*/
public void speak() {
System.out.println(this.getName()+"正在说英语");
}
}
3) toString方法重写(重写成符合业务要求的方法)
public String toString(){
return "["+this.getFirstName()+" "+this.getLastName()+"]";
}
4) 父类私有方法不能被重写
package Override;
class S extends OverrideTest06{
public void dosome() {
System.out.println("这句话按说是看不到的,是因为"
+"这个子类方法无法覆盖父类的私有方法");
}
public void doother() {
System.out.println("当你看到这行文字,是因为"
+"父类的公共方法被覆盖了");
}
}
public class OverrideTest06 {
//测试一下父类中的私有方法能不能被子类方法覆盖
private void dosome() {
System.out.println("当你看到这行文字,是因为"
+"父类的私有方法不能被子类方法覆盖");
}
public void doother() {
System.out.println("这句话按说是看不到的,是因为"+
"这个被子类方法覆盖了");
}
public static void main(String[] args) {
OverrideTest06 son = new S();
son.dosome();
son.doother();
}
}