赞
踩
继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。
例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用。
上述图示中,Dog和Cat都继承了Animal类,其中:Animal类称为父类/基类或超类,Dog和Cat可以称为Animal的子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。
修饰符 class 子类 extends 父类 { //..... }
遵循原则
- 子类会将父类中的成员变量或者成员方法继承到子类中了
- 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了
// Animal.java class Animal{ String name; int age; float wight; public void eat(){ System.out.println(name + "正在吃饭"); } public void sleep(){ System.out.println(name + "正在睡觉"); } } // Dog.java class Dog extends Animal{ void bark(){ System.out.println(name + "汪汪汪~~~"); } } // Cat.Java class Cat extends Animal{ void mew(){ System.out.println(name + "喵喵喵~~~"); } } // TestExtend.java public class TestExtend { public static void main(String[] args) { Dog dog = new Dog(); // dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的 System.out.println(dog.name); System.out.println(dog.age); // dog访问的eat()和sleep()方法也是从Animal中继承下来的 dog.eat(); dog.sleep(); dog.bark(); } }
不管是成员变量还是成员方法,都有两种情况:
(1)子类和父类不存在同名
(2)子类和父类同名
在子类方法中 或者 通过子类对象访问成员或方法时:
1.如果访问的成员变量子类中有,优先访问自己的成员变量。
2.如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
3.如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。
1.通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
2.通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;
父子父子,先有父再有子,即:子类对象构造时,需要先调用父类构造方法,然后执行子类的构造方法。
原因:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子
肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。
class Animal { public String name = "123";//姓名 public int age; public Animal() { System.out.println("Animal()"); } public Animal(String name, int age) { this.name = name; this.age = age; System.out.println("带有2个参数的构造方法!"); } public void eat() { System.out.println(name+" 正在吃饭!"); } } class Dog extends Animal { public Dog() { //super();//编译器会帮你默认加上的 System.out.println("DOG()"); } public Dog(String name,int age) { //super(); super(name,age); //super("七月",10);//显示的调用父类的构造方法,帮助父类的成员进行初始化 } public void wangwang() { System.out.println(name +" 旺旺叫!"); } } class Cat extends Animal { public Cat() { super(); } public int size; public Cat(String name,int age,int size) { super(name,age); this.size = size; } public Cat(String name,int age) { super(name,age); //this("1",2,3); } public void mew() { System.out.println(name +" 正在喵喵叫!"); } } public class Test { public static void main(String[] args) { Dog dog = new Dog(); System.out.println("====="); Dog dog2 = new Dog(); } }
子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成员时,该如何操作?
super和this都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句,那他们之间有什么区别呢?
【相同点】
【不同点】
刚才我们发现, 如果把字段设为 private, 子类不能访问. 但是设成 public, 又违背了我们 “封装” 的初衷.
两全其美的办法就是 protected 关键字.
对于类的调用者来说, protected 修饰的字段和方法是不能访问的
对于类的 子类 和 同一个包的其他类 来说, protected 修饰的字段和方法是可以访问的
// 为了掩饰基类中不同访问权限在子类中的可见性,为了简单类B中就不设置成员方法了 // extend01包中 public class B { private int a; protected int b; public int c; int d; } // extend01包中 // 同一个包中的子类 public class D extends B{ public void method(){ // super.a = 10; // 编译报错,父类private成员在相同包子类中不可见 super.b = 20; // 父类中protected成员在相同包子类中可以直接访问 super.c = 30; // 父类中public成员在相同包子类中可以直接访问 super.d = 40; // 父类中默认访问权限修饰的成员在相同包子类中可以直接访问 } } // extend02包中 // 不同包中的子类 public class C extends B { public void method(){ // super.a = 10; // 编译报错,父类中private成员在不同包子类中不可见 super.b = 20; // 父类中protected修饰的成员在不同包子类中可以直接访问 super.c = 30; // 父类中public修饰的成员在不同包子类中可以直接访问 //super.d = 40; // 父类中默认访问权限修饰的成员在不同包子类中不能直接访问 } } // extend02包中 // 不同包中的类 public class TestC { public static void main(String[] args) { C c = new C(); c.method(); // System.out.println(c.a); // 编译报错,父类中private成员在不同包其他类中不可见 // System.out.println(c.b); // 父类中protected成员在不同包其他类中不能直接访问 System.out.println(c.c); // 父类中public成员在不同包其他类中可以直接访问 // System.out.println(c.d); // 父类中默认访问权限修饰的成员在不同包其他类中不能直接访问 } }
final关键可以用来修饰变量、成员方法以及类,一定要初始化(相当于c语言的const)
final 关键字的功能是 限制 类被继承“限制” 这件事情意味着 “不灵活”. 在编程中, 灵活往往不见得是一件好事. 灵活可能意味着更容易出错.是用 final 修饰的类被继承的时候, 就会编译报错, 此时就可以提示我们这样的继承是有悖这个类设计的初衷的.
修饰变量或字段,表示常量(即不能修改)
修饰类:表示此类不能被继承 , 我们平时是用的 String 字符串类, 就是用 final 修饰的, 不能被继承.
修饰方法:表示该方法不能被重写
1.修饰变量或字段
final int a = 10;//使用final 一定要初始化
a = 20; // 编译出错
2.修饰类
final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 编译出错
Error:(3, 27) java: 无法从最终com.bit.Animal进行继比特就业课
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。