Java SE 学习---继承与多态

来源:互联网 发布:多益网络工资福利 编辑:程序博客网 时间:2024/05/21 08:55
  • super关键字
super关键字用在继承关系的类之间,一般用于在子类中调用父类的方法或者构造函数,例如:
class A{...method1();...}class B extends A{  public void method1(){     super.method1();  }}


类B继承自类A 并重写了A的方法method1() 如果在B的method1中要访问A的mehtod1(为什么要这么访问有可能是B想通过A 的method1获取A的私有域),如果在这里不适用super关键字那么B调用method1时就会陷入无限循环直到程序崩溃。
又如:
class A{...  public A(arg1,arg2){       }...}class B extends A{     public B(arg1,arg2,arg3){    super(arg1,arg2);     ...  }}
由于B类的构造器不能访问A类的私有域,所有必须利用A类的构造器对这部分的私有域进行初始化,这时就需要通过super实现对父类构造器的调用,同时super调用构造器的语句必需时子类构造器的第一条语句。如果子类的构造器没有显示的调用父类的构造器,则将自动地调用父类默认的构造器,如果父类没有不带参数的构造器,并且在子类的构造器中又没有显式的调用父类的其他构造器,java编译器就会报告错误。
  • 多态与动态绑定
一个对象变量可以引用多种实际类型的现象被称为多态,在运行时能够自动的选择调用的适当的方法的现象称为动态绑定。例如:
...B b=new B();A[] arr=new A[3];arr[0]=new A();arr[1]=new A();arr[2]=b;for(A a:arr){  a.method1();}...
arr[2]是类型A的变量但是它却可以引用到B的一个实例上去,同时arr[0].arr[1]调用method1时能够调用A的method1,arr[2]能调用B的method1.

  • instanceof运算符
当一个子类的引用赋给一个超类变量时编译器时允许的,但是将一个超类的引用赋给一个子类变量必须进行类型转换这样才能通过运行时的检查
但是试图在有继承层次关系的类之间进行向下的类型转换时,“谎报”了对象的内容之后,程序在运行时就会报错并产生一个ClassCastException.像这样:
B b2=(B)arr[0];//会报错
因此在进行类型转换之前应该先看一下时候能够成功的转换,这个时候就需要instanceof运算符了。例如:
if(arr[0] instanceof B){   b2=(B)arr[0];}

  • abstract关键字
如果在父类中只声明一个方法,不做具体的实现,那么我们可以将该方法声明为抽象方法,就在方法的声明中加入abstract关键字,像这样:
public abstract String getDescription();//只声明没有实现
同样包含有abstract关键字声明的方法的类必须被声明为抽象类(即用abstract关键字修饰的类)
public abstract class Base {public abstract String getDescription();}
区别于接口抽象类中除了能够包含抽象方法,还可以包含自己的数据域以及具体方法
在抽象类的实现子类中,如果子类实现了抽象类的所有抽象方法,那么该子类就不是抽象的了。如果子类只实现了一部分父类(抽象类)的抽象方法,那么子类也必须被声明为抽象的。如果一个类不含抽象方法,也可以将这个类声明为抽象类。抽象类不能实例化,但是可以定义一个抽象类的变量,它可以引用非抽象类的对象.例如:
public class BaseImpl extends Base{...}Base base=new BaseImpl();
这一点和接口和他的实现类的使用方式很相似。
  • Java访问可见性

  • Object类
Object类时Java中所有类的父类(确切的说应该是祖先类),Java中除了基本类型(数值,字符和boolean)的值不是对象,其他任何的类型都是对象(包括数组)。Object定义了一些基本的方法,这也意味中Java中所有的类都继承了这些方法。
  1. equals方法,equals方法用于检测一个对象是否等于另外一个对象,关于equals方法的一些说明,参见我之前的一篇blog,这里不再赘述。
  2. hashCode方法,hashCode方法用于计算对象的散列码,在默认情况下和其他对象的散列码是对象的存储地址不一样,String类型的对象的散列码是由字符串的内容计算而得到的。equals与hashCode的定义必须一致,如果x.equals(y)返回true,那么x.hashCode()就必须与y.hashCode()具有相同的值。
  3. toString方法,用于返回表示对象值得字符串,绝大多数类的toString方法都遵循这样的格式:类的名字,一对方括号括起来的值域。
  • 包装器类
有时需要将int这样的非基本类型转换为对象。所有的基本类型都有一个与之对应的类,例如Integer类对象对应基本类型int,通常这些类就叫做包装器类。包装器类有Integer,Long,Float,Double,Short,Byte,Character,Void和Boolean,包装器类时不可变的不允许更改包装在其中的值,同时包装器类还是final的,因此不能定义他们的子类。在整形数组列表中尖括号中的类型参数是不允许时基本类型的而只能是基本类型对应的包装器类。例如:
ArrayList<int> list=new ArrayList<int>();//错误ArrayList<Integer> list=new ArrayList<Integer>();//正确
在JDK5.0以后的版本中对于存取包装器中的数据提供了打包和拆包机制,如:
list.add(3);//会对int类型的参数打包成new Integer(3)//自动转换成list.add(new Integer(3));
int n=list.get(i);//会对get出来的Integer自动拆包//自动转换成int n=list.get(i).intValue();
当使用''=='运算符来判断数值包装类是否相等时要注意,由于包装器变量会根据数值的大小来决定多个变量会不会指向同一块存储区域,因此会造成判断的不一致,例如:
这是由于自动打包规范要求byte,char<=127,介于-128~127之间的short和int被包装到了固定的对象中了。在上图中int 100由于在-128~127之间,所以Integer变量a,b都指向了同一块的存储区域,由于“==”运算符比较的是地址,所以第一次比较的时候a与b相等,第二次比较时由于int 1000超出了-128~127的范围,所有a,b指向了不同的对象的存储区域用“==”运算符来比较这两个对象肯定不相等。



0 0