Java 课堂记录 03 (继承与多态)

1、
Overriding:子类在继承父类方法的同时并改写了此方法。(方法名称,参数个数,类型都不变).

继承关系里,在子类中使用super关键字调用父类的方法可以增强子类的可维护性。(黑盒机制)
父类成员的引用 : super.成员变量; super.成员方法;  调用父类的构造方法 super(参数列表).

在子类对象创建的时候,初始化的顺序是:1. 父类中的构造函数; 2. 子类的属性初始化; 3. 子类的构造函数。
1.在创建子类时默认的情况( 不指定带参super(..) )下是调用父类中不带任何参数的构造函数,如果父类中不存在此构造函数就会编译出错。
2.在构造函数中可以通过super(...)来调用父类的构造函数,其效果和默认的情况下是一样的。
3.super()用于调用父类的构造函数只能够出现在子类中,且必须出现在子类构造函数的第一行。

因为 protected 可以在不同包之间访问( 对象访问成员), 所以 protected 可以在不同包之间继承( 出现在继承类中)。 同理 default 可以在同包之间访问,所以可以在同包之间继承。
在不同包的子类中也不能够访问protected类型修饰的成员。
final : 修饰方法:方法不能被重写;   修饰类 : 不能被继承。
java中的每一个类都是对Object的一个扩展,但是绝对不可以直接继承自Object:eg class student extends Object是错误的。
System.out.println( .. )在输出一个对象时,系统会调用对象的toString()方法. 否则会出现类似“ @ad3ba4 ”的错误,所以在需要进行输出的对象的类中需显示定义 public String toString(..).

绑定 :建立method call和method body的关联。
多态:多个类提供相同名称的函数。分为 编译时多态(overloading) + 运行时多态(原因: 继承链中的类型转换 + overriding + 动态绑定
向上转型 : upcasting :子类的引用赋值给父类的引用,即子类的对象空间通过父类的引用来访问。产生接口窄化,
接口窄化 : 编译时只允许访问父类中提供的方法(具体哪些受访问权限限制),如果子类中有该方法,则在运行时采用“动态绑定”机制访问子类方法。
向下转型 : 必须使用 if(obj1 instaceof  subclass) s = (student)p;  判断。
Static 方法 :
1、被隐藏的父类中的静态方法不能够从子类中访问。
2、Static修饰的方法是可以在子类中继承的,但是在执行upcasting之后,静态方法不会出现动态绑定的现象。

2、代码验证 Test.java
class Person{   
   private String name;
    private int age;
    static int temp;
    public Person()  {}
    public Person(String n ){  name = n; }
    public void setName(String n){  name = n ;  }
    public String getName(){ return name; }
    public void myInfo(){      System.out.println("My name is:"+name );   }
    public static void testStatic(){   System.out.println("In SuperClass test static!");  }
    public  void testNoStatic(){   System.out.println("In SuperClass test no static!");   }
 }


class Student extends Person
{
 String major;
 public Student()  { }
 public Student( String str, String str_major){ super( str );    major = str_major; }
 public void setMajor( String s )  { major = s; }
 public void myInfo() {  super.myInfo();    System.out.println("My major is:"+ major + "/n" );  }
 public static void testStatic(){   System.out.println("In SubClass test static!");  }
  public  void testNoStatic(){   System.out.println("In SubClass test no static!");   }
//  super.testStatic();  // Error :  子类不能访问父类中被隐藏的static方法。
 int temp = super.temp ;  // OK : 子类能访问父类中被隐藏的static属性。
 }

public class Test
{
 public static void main( String[] args )
 {
  Person zp_p = new Person( "ZP_P" );
  Student zp_s = new Student( "ZP_S", "SEI" );
  zp_p.testNoStatic();  zp_p.testStatic();
  zp_p = zp_s;   System.out.println( "/nAfter dynamic binding /n" );
  zp_p.testNoStatic();  zp_p.testStatic();  // 只有testNoStatic 发生了动态绑定。

  zp_p.myInfo();  // 因为zp_p 的定义类型Person 中也有myInfo(),所以编译通过,运行时动态绑定。  
  dynamicBind( zp_s );  // 因为对象应用做形参是传值,动态绑定。
  
  Person[] persons = new Person[1];
  persons[0] = zp_s;
  persons[0].myInfo();  // 因为对象数组中每个位置存放的是引用,动态绑定。
  
// zp_p.setMajor( "Economy" );   
// Error : 找不到符号 :符号: 方法 setMajor(java.lang.String)。因为编译器只知道zp_p 是Person 类型,而Person 类中没有setMajor() 方法。
  Student zp_s_new = null;
//  zp_s_new = zp_p;
//   Error :  不兼容的类型, 找到: Person,  需要: Student. 因为未用 instanceof 判断的向下转型是不安全的,编译器统统禁止。
  if( zp_p instanceof Student )  { zp_s_new = (Student)zp_p;  System.out.println( "OK, safe DownCasting " ); }  
 }
 
 public static void dynamicBind( Person prs ) { prs.myInfo(); }  
}

输出为 :
In SuperClass test no static!
In SuperClass test static!

After dynamic binding

In SubClass test no static!
In SuperClass test static!
My name is:ZP_S
My major is:SEI

My name is:ZP_S
My major is:SEI

My name is:ZP_S
My major is:SEI

OK, safe DownCasting
 

你可能感兴趣的:(JAVA)