一、高级类特性
1、static关键字(访问时,“类名.静态属性”,“类名.静态方法”)
静态变量
静态方法
静态内部类
static不可用于修饰构造器,因为构造器是属于对象本身的。而static修饰的成员只属于类本身。
static成员产生的时机是在类加载的时候。这个时候本类的对象还没有产生。
因此,static方法只能访问静态成员(
静态方法、
静态属性)。
非静态的成员属于对象本身。
非静态方法可以访问静态成员。
2、static初始化块
static自由块只在类加载时执行一次,与创建多少个对象无关,通常用于初始化静态变量。
示例参第三天初始化代码块例程,在person和teacher类中分别添加static初始化代码观察执行结果如下:
3、final关键字
用于修饰类、方法和变量
用final修饰的类不可被继承
如:java.lang.Math
java.lang.String
用final修饰的变量在初始化后不可改变变量值,用于常量定义;
如果变量是引用变量,则不可以改变它的引用对象,但可以改变对象的数据(属性)
用final修饰的方法不可被覆盖
类似C/C++中的const关键字概念
4、abstract关键字
用来修饰一个类或者方法,用abstract修饰的类表示这个类是一个抽象类,用abstract修饰的方法表示这个方法是一个抽象方法。
抽象类不能被实例化,必须被继承后覆盖了所有的抽象方法后才可以实例化。
抽象方法只有方法声明,没有方法的实现。(相当于C语言中函数的前置声明)
注意区分没有实现的方法和没有方法体的方法。
1)public void methodA(); //没有实现的方法
2)public void methodB(){} //没有方法体的方法
假设A类中有三个抽象方法,B类继承A类,B类实现了其中两个抽象方法,B类必须要声明成抽象类,仍然不能被实例化。
抽象类里面并非一定需要抽象方法,但是没有抽象方法,抽象类就没有定义成抽象的必要。
在以下任一条件成立时,类必须定义成抽象类:
1)类中有至少一个抽象方法
2)类继承了父类中的抽象方法,但是至少有一个抽象方法没有实现
3)类实现了某个接口,但没有全部实现接口中的方法
抽象类程序示例:
Abstractcc.java
|
Delta.java
|
four.java
|
package cn.com.farsight.java;
public abstract class Abstractcc {
public abstract double perimeter();
public abstract String getType();
}
|
package cn.com.farsight.java;
public class Delta extends Abstractcc {
private int a, b, c;
@Override
public double perimeter() {
// TODO Auto-generated method stub
return a + b + c;
}
@Override
public String getType() {
// TODO Auto-generated method stub
return "三角形";
}
}
|
package cn.com.farsight.java;
public class Four extends Abstractcc {
private int a, b, c, d;
@Override
public double perimeter() {
// TODO Auto-generated method stub
return a + b + c + d;
}
@Override
public String getType() {
// TODO Auto-generated method stub
return "四边形";
}
}
|
5、单例设计模式
一个类只能有一个实例。
6、接口(interface)
接口可使用“extends”从父接口中派生;和类不同的是,一个接口可以继承多个父接口。
多个无关的类可实现同一个接口,一个类可实现多个无关的接口。
接口是抽象方法和常量值的定义的集合。
接口是一种特殊的抽象类。
接口可以实现多继承。
接口是一种功能,带有策略性的、纲领性的规范。在JAVA中,可以通过接口来模拟多继承,接口的多继承就是功能的扩展,它可以完成C++中类的多继承所完成的任务。
如果一个类实现了某个接口,这个类实例化成对象,这个对象被称为是这个接口的子类对象。
在接口中定义的方法比如:void comm();
隐含着public abstract void comm();
接口程序示例:
接口
| 智能手机类宝义 |
1、交流工具接口
interface CommTools{
void comm();
}
2、播放器接口
interface MediaPlayer{
void play();
}
| public class SmartPhone implements CommTools, MediaPlayer{ //从CommTools中继承 public void comm(){ System.out.println("打电话"); } //从MediaPlayer中继承 public void play(){ System.out.println("听歌曲"); } } |
7、多态(Polymorphism)
示例1:CellPhone是Phone的子类, Phone p; p = new
CellPhone();
以多态的形式来传递参数,增强了参数类型的灵活性。
程序示例2:
一个对象只能有一种确切的数据类型
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法。(如上例中watchHome()方法仅仅在dog子类中定义,那么xiaobai.watchHome()需要进行强制类型转换成((dog)xiaobai).watchHome();或者在Animal父类中添加
watchHome()方法)
父类引用可以指向子类对象。
在语法上分为:
编译时 编译器会按照引用类型来判断语法
运行时 JVM会根据对象的实际类型来执行相应版本的方法
8、instanceof运算符
使用该运算符可以等到对象的类型
对象造型(Casting)
所谓造型就是Java对象间的类型转换
Java的对象造型可以分为两种情况:
自动造型和强制造型
在造型前可以使用instanceof运算符测试一个对象的类型。
对象的造型只用在有继承关系的对象之间。
9、内部类
允许一个类的定义出现在另一个类中,将处于另一个类中的"寄生类"称为"内部类"(innerclass),也称为"类属类",这样的一组类在逻辑上是一个整体,内部类和外层封装它的类之间在逻辑上的从属关系,内部类对其封装类的内部成员有访问权限。
示例 |
public class Outer1{
private int size;
public class Inner{
public void doStuff(){
size++;
}
}
public void testTheInner(){
Inner i = new Inner();
i.doStuff();
}
}
|
实例化内部类(两种方法)
1)Outer1.Inner in = new Outer1().new Inner();
2)Outer1 o = new Outer1();
Outer1.Inner I = new Inner();
如果内部类是static修饰的,也可以用这种方法:Outer1.Inner in = new Outer1.Inner();
内部类特性:
1)、类的名字只能在定义的范围内使用,除非使用有效的全名Outer1.Inner;
在内部类中引用外部类当前的对象,要使用以下形式:
Outer.this
此时的this指的是正在创建的内部类对象
2)、
Inner类也可以定义在方法的内部。方法中final类型的局部变量,都可以被Inner类的方法访问。
在内部类中,若为了访问外部类中所定义的局部变量,此局部变量必须要使用final修饰。
3)、Inner类可以声明为抽象类,因此可以被其它的内部类继承。也可以声明为final的。
4)、
内部类作为外部类的成员,静态的只能访问静态的外部类成员。
5)、非static的内部类中的成员不能声明为static的,只有在顶层类或static的内部类中才可声明static成员。
6)、含区别中的1、2条
内部类与普通类的区别
1)、内部类可以使用static修饰,外部类不可以,但此时就不能再使用外层封装类的非static的成员变量。
2)、内部类可以使用protected和private修饰,
外部类不可以
3)、内部类可以访问封装类中的私有成员,外部类中的方法不可以访问内部类中的私有成员。
外部类(独立)不可以访问其他类的私有成员
匿名内部类
匿名内部类就是没有名字的内部类
一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
在以下情况中,可以考虑使用匿名内部类:
只用到类的一个实例。
类在定义后马上用到。
类非常小。
给类命名并不会导致你的代码更容易被理解。
抽象类与接口的区别
1)、抽象类只支持单继承,接口支持多继承
2)、抽象类中可以包含已经实现的方法,接口中只能包含抽象方法和常量。
3)、子类只能继承一个抽象类,可以实现多个接口。
10、修饰符
三、异常处理
1、异常概念
Java中所有的异常和错误的父类是Throwable
2、异常示例
捕获异常(数组越界、除数为零) |
|
示例程序中ArrayIndexOutofBoundsException e也可替换成Exception e,但此时要注意有多条catch时,因为Exception是能捕获所有异常的,所以需要将Exception e 这条异常catch放在最后。
3、异常分类
1)error——动态链接失败,虚拟机错误等,通常Java程序不应该捕获这类异常,也不会抛弃这种异常。
2)Exception
运行时异常——继承于RuntimeException,Java编译器允许程序不对它们做出处理。
非运行时异常——除了运行时异常之外的其他由Exception继承来的异常类。
Java编译器要求程序必须捕获或者声明抛弃这种异常。
4、异常处理
1)调用者继续抛出异常对象
2)try...catch...[finally]进行处理,捕获异常
try{
//可能会抛出特定异常的代码段
}catch(someException excp){
//如果excp被抛出,则执行这段代码
}[finally{
//无条件执行的语句,常用于资源的清理,如关闭文件,关闭数据库连接等。
}]
Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统(JRE),这个过程称为抛出(throw)异常
一个try块可以和多个catch块配合以处理多个异常
使用多重catch语句时,异常子类一定要位于异常父类之前
5、自定义异常类
1)需要继承自Exception类
2)注意throw和throws的区别
示例:小孩上幼儿园