继承: (不会产生覆盖)子类继承父类的方法,当子类去调用该方法时,如果该方法内用到了一个 成员变量 在父类和子类都有该成员变量,那么他会用父类的。即 子类调用父类方法,里面所有变量都是用父类中的,自己定义没用
继承内存图,circle 是父类,cylinder继承circle;
继承中构造函数初始化:
显式初始化:可以在子类构造函数的第一条语句通过 super() 或 super(…) 调用父类的默认构造函数或特定签名的构造函数,系统默认也会提供;
当父类没有提供默认构造函数时,必须在子类构造函数第一条语句通过 super(…) 完成父类对象成员的初始化工作;
class A{
int a,b;
A(int c, int d){
a=c;
b=d;
}
}
|
class B extends A{
int c;
B(int i, int j, int k){
super(i, j);
c=k;
}
|
Hiding Fields (隐藏域):
域不能被覆盖,只能被隐藏,子类可以通过声明与父类或祖先类中的域同名的域来实现对父类或祖先类中的域的隐藏
要访问父类或祖先类中被隐藏的域必须通过super引用,即 super.hiddenField
当通过对象引用访问对象的域的时,域的值由对象引用所属的类型决定,并不由被引用的对象的实际类型决定
super 引用:
保留字 super 可以在任意的非静态方法中使用,super可以看作当前对象实例所对应的父类型的实例引用,通过super引用可以访问属于父类实例的域和方法,通常这些域和方法被当前类隐藏或被覆盖了
final 的用途:
被final修饰的类不能被继承,被final修饰的方法不能被覆盖
使用final修饰类和方法可以提高安全性
使用final修饰类和方法可以加快某些类型检查过程
Packaging Classes:
在Java源程序文件的第一行使用 package 声明可以使文件中定义的类成为指定包的成员
package声明的语法如下:
package <包名>;
包名通常由多个名字字符串构成,中间用句点“.”分隔,每个名字表示的包称为其前面的名字表示的包的子包,通常以组织机构的域名反转形式作为其所有包的通用前缀,如
com.somecompany.apps
包有以下用途:
(1) 将相关的类和接口分组,包名通常表示包中各个类和接口的用途
(2) 包创建了不同的命名空间(Namespace),从而有效地解决了类型命名冲突问题
(3) 包提供了对应用程序内部实现机制的保护域
***当一个类中引入了一个包,程序要new一个对象,这个对象在类所在包和引入的包中都含有,默认new的是引入包的对象;如果要new出类所在包的其他类的对象,就要加类限定符:com.new对象类包名 类名 = new com.new对象类包名 () ;
Type Imports:
在类名前面加上类所属的包名,中间用句点“.”分隔,称为类的完全限定名(Full Qualified Name),简称类的限定名
当在类体中使用了与当前类不同包的类名时,编译器编译时因为无法找到该类的定义而失败,有两个解决办法:
(1) 使用不同包类的完全限定名
(2) 使用import声明,为编译器提供该类的定义信息
多态:
//父子关系 //方法覆盖 //父类引用指向子类对象
多态中,父类的引用指向子类的实例,如果调用该方法有覆盖,则优先调用子类的;其他的都没有特例,一律调用父类自己的。
方法覆盖是指在子类中替换父类或祖先类对某个方法的实现。
方法覆盖通过子类重新定义与父类或祖先类中具有同样签名和返回类型的方法实现。
被final修饰的方法不允许在子类中覆盖。
其它修饰符,如synchronized、native可以在覆盖的方法声明中自由使用
父类被覆盖的方法的参数列表中被声明为 final 的参数在子类的覆盖方法的中可以不必指定为final(可以更改)
子类覆盖方法声明的异常列表中的异常类必须与父类被覆盖方法声明的异常列表中的异常类兼容(相同或是其子类)
只有在子类类体中可以访问的父类或祖先类的方法才能被覆盖
多态的优点:提高代码的可维护行、提高代码的扩展性
多态的弊端:不能使用子类的特有功能
如何解决
法1:创建子类对象调用子类方法
法2:把父类的引用强转为子类引用 (向上转型:Animal animal = new Dog(); 向下转型:Dog dog = (Dog) animal;)
package com.java.多态;
public class Demo2 {
public static void main(String[] args){
Cat2 cat2=new Cat2();
//cat2.eat();
//cat2.sleep();
keepCat(cat2);
Dog dog=new Dog();
dog.eat();
dog.sleep();
Pig pig=new Pig();
pig.eat();
pig.sleep();
keepAnimal(cat2);
keepAnimal(dog);
keepAnimal(pig);
}
public static void keepAnimal(Animal2 animal2){
animal2.eat();
animal2.sleep();
}
public static void keepCat(Cat2 cat2){
cat2.eat();
cat2.sleep();
}
public static void keepDog(Dog cat2){
cat2.eat();
cat2.sleep();
}
public static void keepPig(Pig cat2){
cat2.eat();
cat2.sleep();
}
}
|
class Animal2{
public String Weight;
public void eat(){
System.out.println("Animal2 eat()");
}
public void sleep(){
System.out.println("Animal2.sleep()");
}
}
class Cat2 extends Animal2{
public String Weight;
public void eat(){
System.out.println("Cat2 eat() fish");
}
public void sleep(){
System.out.println("Cat2.sleep() in day");
}
}
|
class Pig extends Animal2{
public String weight;
public void eat(){
System.out.println("Pig eat() rice");
}
public void sleep(){
System.out.println("Pig sleep() in all day");
}
}
class Dog extends Animal2{
public String weight;
public void eat(){
System.out.println("Dog eat() meet");
}
public void sleep(){
System.out.println("Pig sleep() in night");
}
}
|
多态中成员访问的特点
成员变量
编译看左边,运行看左边
函数
编译看左边,运行看右边
A.java
public class A {
protected void f() {
System.out.println("A.f()");
this.g();
}
protected void g() {
System.out.println("A.g()");
}
}
|
B.java public class B extends A {
@Override //ALT+/
protected void g() {
System.out.println("B.g()");
}
}
//运行结果
|
Test.java public class Test {
public static void main(String[] args) {
B b=new B();
A a=new B();
a.f();
b.f();
B b1=(B)a;
b1.f();
}
|