学习注意
- 虽然知识看上去简单,但实际上并没有看上去那么简单。战略上藐视敌人,战术上重视敌人。
- 一定要动手试验,积极进行技术探索
“IS_A"关系(继承关系)
“继承者拥有被继承者的一切基本特性,但同时又拥有自己的独特的特性”
- 语法:
class subclassname extends superclassname{..}
子类自动拥有父类声明为public和protected的成员
继承条件下类的访问权限
public:外界可自由访问
private:外界不可访问
protected:同一包中的子类都可以访问,另一包中的子类(派生于同一个父类)也可以访问
default:如果不指明任何权限,则默认同一包中的类可以访问
继承条件下构造方法调用
class Grandparent {
public Grandparent() {
System.out.println("GrandParent Created.");
}
public Grandparent(String string) {
System.out.println("GrandParent Created.String:" + string);
}
}
class Parent extends Grandparent {
public Parent() {
//super("Hello.Grandparent.");
System.out.println("Parent Created");
//super("Hello.Grandparent.");
}
}
class Child extends Parent {
public Child() {
System.out.println("Child Created");
}
}
public class welcome1
{
public static void main(String args[]) {
Child c = new Child();
}
} // end class RegexMatches
使用super关键字,通过super调用基类的构造方法,必须是子类构造方法的第一句,否则报错
- super关键字:子类中的方法和成员变量如果和父类一致,子类的优先级高,如果想用超类中成员和方法,就要用super
不允许继承的类
final class 类名{…}
- 以final声明的方法不允许覆盖
- 以final声明的变量不允许修改
- 利用final可以设计只读类
何为不可变类?
- 创建“不可变类”的对象后,此对象的属性不可改,而且也无法从此类派生出新子类
- 用途:可以方便和安全地用于多线程环境中,访问它们可以不用加锁,因而能提供较高的性能
public final class Address
{
private final String detail;
private final String postCode;
//‘⁄ππ‘Ï∑Ω∑®¿Ô≥ı ºªØ¡Ω∏ˆ µ¿˝ Ù–‘
public Address()
{
this.detail = "";
this.postCode = "";
}
public Address(String detail , String postCode)
{
this.detail = detail;
this.postCode = postCode;
}
//ΩˆŒ™¡Ω∏ˆ µ¿˝ Ù–‘÷π©getter∑Ω∑®
public String getDetail()
{
return this.detail;
}
public String getPostCode()
{
return this.postCode;
}
//÷ÿ–¥equals∑Ω∑®£¨≈–∂œ¡Ω∏ˆ∂‘œÛ «∑Òœ‡µ»°£
public boolean equals(Object obj)
{
if (obj instanceof Address)
{
Address ad = (Address)obj;
if (this.getDetail().equals(ad.getDetail()) && this.getPostCode().equals(ad.getPostCode()))
{
return true;
}
}
return false;
}
public int hashCode()
{
return detail.hashCode() + postCode.hashCode();
}
}
源码之前,了无秘密
class A
{}
public static void main()
{
System.out.println(new A());
}
输出为welcome.A@448139f0
解释:实际上println调用了String类的valueOf方法
public void println(Object x) {
String s = String.valueOf(x);
if (getClass() == PrintStream.class) {
// need to apply String.valueOf again since first invocation
// might return null
writeln(String.valueOf(s));
} else {
synchronized (this) {
print(s);
newLine();
}
}
}
valueOf方法调用了Object类的toString方法
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
toString方法中调用hashCode:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
hashCode方法是本地方法,由JVM设计和开发者提供具体实现:
public native int hashCode();
关于native关键字
native是与C++联合开发时候用的!Java自己开发不用的!
- 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成DLL,由java去调用
- 这些函数的实现体在DLL(动态链接库)中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的,这也是Java的底层机制,实际上Java就是在不同的平台上调用不同的native方法实现对操作系统的访问。
- native是用做java和其它语言协调时用的,也就是native后面的函数不是用Java写的
- native的意思就是通知操作系统,这个函数你必须给我实现,因为我要使用,所以native关键字的函数都是操作系统实现的,Java只能调用
- Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
可以将native方法比作Java程序同C程序的接口,其实现步骤:
1、在Java中声明native()方法,然后编译;
2、用javah产生一个.h文件;
3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
4、将第三步的.cpp文件编译成动态链接库文件;
5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。- JAVA本地方法适用的情况
1. 为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问
2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的
3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
子类与父类方法之间的关系
- 由于Java并未对子类方法的命名做过多的限制,因此,子类与父类各自自定义的方法之间,可以出现以下三种情况:
- 扩充(extends):子类定义的方法父类没有同名
- 覆盖/重写(override):子类父类定义了完全一样的方法
- 重载(overloads):子类有父类的同名方法,但两者的参数类型或参数数目不一样
顶层基类Object
重写方法比如在String输出的时候使用+,就是在+运算时,当任何一个对象与一个String对象连接时,会隐式调用其toString方法,默认情况下此方法返回类名@+hashCode()。为了返回有意义的信息,子类可以重写toString方法
方法覆盖(override)
- 方法覆盖要求子类与父类的方法一摸一样,否则就是方法重载
- 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字(被覆盖不是这个方法没了,而是有同样的方法,比它优先级要高)
- Java方法覆盖的语法规则:
- 覆盖方法的允许访问范围不能小于原方法
- 覆盖方法所抛出的异常不能比原方法多
- 声明为final方法不允许覆盖。例如Object的getClass方法不能覆盖
- 不能覆盖静态方法