首页 > 代码库 > Java继承
Java继承
java 和某些面向对象语言(如 c++)在实现继承的不同之处在于java只支持单继承,不支持多重继承。即java 中一个类只能继承于另一个类。我们将被继承的类称之为父类(基类),继承类称之为子类(派生类)。在java 中用关键字extends 来实现单继承。在前面所讲已知,实现继承关系的类之间有着必然的联系,不能将不相关的类实现继承,就象人类不能继承于鸟类!
那怎么去判断类和类之间是否有着必然联系呢?实际上,前面我们已知当某类A和类 B之间有着共同的属性和行为时,那么类A 和类 B之间就可能是继承关系或者有着共同的父类。继承带来了三个好处:减少代码冗余;维护变得简单;扩展变得容易。构造方法不能被继承!一个类得到构造构造方法只有两种途径:自定义构造方法;使用JVM分配的缺省构造方法。但是,可以在子类中访问父类的构造方法,后面我们会深入。
在java中是通过各种访问限定符来实现数据封装的,共分为四种访问级别(由高到低):
private(私有)、friendly(缺省)、protected(受保护)、public(公共)。注意:以上四种访问修饰符可以作用于任何变量和方法,类只可以定义为默认或公共级别(嵌套类除外)。
public(公共)
当变量或方法被public修饰时,该变量和方法可以在任何地方(指的是任何包中)的任何类中被访问;
protected(受保护的)
当类的变量或方法被 protected 修饰时,该变量和方法只可以在同包中的任何类、不同包中的任何当前类的子类中所访问。即不同包中的任何不是该类的子类不可访问级别为protected的变量和方法。
friendly(缺省的)
当类的变量和方法没有显式地被任何访问区分符修饰时,该变量和方法的访问级别是缺省的。缺省的变量和方法只能在同包的类中访问。
private(私有的)
被 private 所修饰的所有变量和方法只能在所属类中被访问。即类的私有成员和变量只能在当前类中被访问。
对于java 编译器来说,它只依据方法的名称、参数列表的不同来判断两个方法是否相同,如果出现两个名称相同、参数也完全一致的方法,那么编译器就认为这两个方法是完全一样的,也就是说方法被重复定义!
通过重载,可以在一个类中定义相同名称、不同参数的实现相同功能的多个方法,这样就避免了给每个方法取不同名称、熟记每个不同名的方法对应的功能的额外工作量,提高了我们的开发效率。当一个类中的多个同名方法满足以下条件时之一时,即实现了方法重载:
a. 不同的参数个数
b. 不同的参数类型
c. 不同的参数顺序
如果有一个类带有几个构造函数,那么也许会想复制其中一个构造函数的某些功能到另一个构造函数中。可以通过使用关键字this作为一个方法调用来达到这个目的。对于this的任何调用,如果出现,在任何构造函数中必须是第一个语句。构造函数中调用另一构造函数,其调用(this()、super())有且只能有一次,并不能同时出现调用。
覆盖是基于继承的,没有继承就没有覆盖。在 java 中,覆盖的实现是在子类中对从父类中继承过来的非私有方法的内容进行修改或扩展的一个动作(注意:不能违反访问级别的限制,即子类方法的访问级别不能低于父类方法的访问级别)。
实现方法的覆盖必须满足以下所有条件:
a. 覆盖方法的方法签名(方法名,参数,返回类型)必须与被覆盖方法的方法签名相同
b. 覆盖方法的访问级别不能比被覆盖方法访问级别低
c. 覆盖方法不能比它所覆盖的方法抛出更多的异常。
在 java 中的多态就体现在一个变量可以引用多个不同类对象,前提是这些不同类必须有者共同的父类,从而该变量可以且只能调用每个不同对象之间的公共操作集(方法)。父类引用可以引用子类对象,同时该父类引用只能访问所有子类的公有操作集(从父类继承过来的成员);当子类中已覆盖继承方法时,父类变量调用的将是子类中的已覆盖方法!
Extends Object是JVM自动给任意类加上去的,从而保证 java中的所有类都具备一个通用父类。既然Object是所有类的父类,那么我们就可以通过Object 数组来实现异类收集,由于多态性,Object数组就能收集所有种类的元素。
父类的私有方法对于子类来说是不可见的,注意,不可见不等于没有,子类仍旧继承了父类所有的成员,那么这些私有的父类成员去哪了?实际上,它们都被隐藏,对子类来说,这些父类的私有成员都被隐藏了起来,从而导致子类中的不可见。
我们通过super关键字显示地调用父类的构造函数,当然,也可以象使用this对象一样通过super调用父类的成员方法。比如:super.m1()等 但是,必须得注意:父类构造函数只能在子类构造函数中通过 super 显示调用,并且必须是第一句!
对于每一个 java 基本数据类型,java 都提供了对应的包装类,如:Boolean、Character、Integer、Double 等8 种包装类。 在java中,包装类主要是用于将基本数据类型与对象之间进行转换连接。
在5.0中java已实现了自动装、拆箱,即基本类型和对应的包装类之间可以直接赋值,
转换的工作由虚拟机代劳了!Integer numObj = 10;语句是正确的!其中基本类型到包装类的自动转换我们称之为自动装箱,反过来就是自动拆箱,比如:
Integer numObj = 10; //自动装箱
int num = numObj; //自动拆箱
因为 java是面向对象语言,我们在许多场合都会将基本类型作为一个对象来处理,因此,包装类就起到了很方便的作用!
包装类有许多共同的方法和静态常量:
valueof(***) --static方法,将对应的基本类型转换成包装类
parseXXX(String) --static方法,将字符串转换成对应的基本类型
toString() --static方法,将基本类型转换成字符串对象
SIZE --静态常量,返回对应基本类型占用的字节位大小
TYPE --静态常量,返回对应的基本数据类型名称
在java中,==与equals()都是用来比较引用,只是==即可以比较基本类型,也可以比
较对象,而 equals()则只能在对象之间进行引用比较。==是对栈中的值进行比较的,如果要比较堆中对象的内容是否相同,那么就要重写equals方法了。 Object类中equals是使用==比较的,所以如果没重写equals方法,和==是一样的效果。Object类中的hashCode是返回对象在内存中地址转换成的一个int值(可以当作地址看)。如果没有重写hashCode方法,任何对象的hashCode都是不相等的。通常集合类需要重写hashCode方法和equals方法,因为如果需要给集合类如HashSet添加对象,那么在添加之前需要查看集合里是否已经有了改对象,比较好的方式就是用hashCode。基本类型封装类也都重写了equals和hashCode方法。
public boolean equals(Object o) {
boolean result = false;
if ((o != null) && (o instanceof Employee)) {
Employee e = (Employee) o;
if (name.equals(e.name)) {
result = true;
}
}
return result;
}
public int hashCode() {
return (name.hashCode());
}
toString 方法被用来将一个对象转换成String 表达式。当自动字符串转换发生时,它
被用作编译程序的参照。例如:
Date now = new Date()
System.out.println(now)
将被翻译成:
System.out.println(now.toString());
对象类定义缺省的 toString()方法,它返回完整类名称+@+引用地址(通常情况下不是
很有用)。许多类覆盖 toString()以提供更有用的信息。所有的包装类覆盖toString()以提供它们所代表的值的字符串格式。甚至没有字符串格式的类为了调试目的常常实现toString()来返回对象状态信息。
本文出自 “wudao” 博客,请务必保留此出处http://chenqi998.blog.51cto.com/8303182/1529521