第五章 高级类的特性2
5.1关键字:static
1.类变量和实例变量
public class Chinese{
//类变量不用实例化,直接类名.属性名就可以使用,是类的一部分,被所有这个类的实例化对象所共享 也可以叫做静态变量
static String country;
//实例变量,只有实例化之后才能使用,属于实例化对象的一部分,不能共用。
String name;
int age;
}
类变量
//类变量应用举例
public class Perosn {
private int id;
public static int total = 0;
public Person(){
total++;
id = total;
}
public static void main(String args[]){
Person Tom = new Person();
Tom.id = 0;
total = 100;//不用创建对象就可以访问静态成员
}
}
//==================================================\\
public class OtherClass{
public static void main(String args[]){
Person.total = 100;//不用创建对象就可以访问静态成员
//访问方式:类名.类属性,类名.方法
System.out.println(Person.total);
Person c = new Person();
System.out.println(c.total);//输出101
}
}
类方法
**因为不需要实例就可以访问static方法,因此static方法内部不能有this、super **
重载的方法需要同时为static的或者非static的。
如果想让一个类的所有实例共享数据,就用类变量!!!
2.类属性、类方法的设计思想
3.单例(Singleton)设计模式——饿汉式
单例模式,软件的运行有且只有一个实例化对象(只会new一次)
public class Single {
//私有的构造,构造方法私有化,调用这个类的人就不能直接使用new来创建对象
private Single() {
}
//私有的Single类型的类变量
private static Single single = new Single();
public static Single getInstance() {
return single;
}
}
//========================================\\
public class Text {
public static void main(String[] args) {
//new只用到了一次
Single s = Single.getInstance();
Single s1 = Single.getInstance();
Single s2 = Single.getInstance();
Single s3 = Single.getInstance();
Single s4 = Single.getInstance();
}
}
饿汉式,是在类加载之后,还没有人调用的时候,就先new好一个对象,以后不论谁来调用getInstance方法,都是直接返回之前new好的那个对象。
4.单例(Singleton)设计模式——懒汉式
public class Single1 {
//先私有化构造方法,让外边不能直接new对象
private Single1() {
}
private static Single1 s1 = null;
public static Single1 getInstance() {
if(s1 == null) {
s1 = new Single1();
}
return s1;
}
}
//===============================================\\
public class Text {
public static void main(String[] args) {
Single1 s = Single1.getInstance();
Single1 s1 = Single1.getInstance();
Single1 s2 = Single1.getInstance();
Single1 s3 = Single1.getInstance();
Single1 s4 = Single1.getInstance();
}
}
懒汉式,最开始对象是null,在第一次有人调用getInstance方法是来new对象,以后再有人调用getInstance方法直接就返回之前第一次new好的对象。
5.2再谈main方法
5.3初始化块
1.初始化块作用
对Java对象进行初始化
2.程序的执行顺序
1.声明成员变量的默认值
2.显示初始化、多个初始化块依次被执行
3.构造器再对成员进行赋值操作
3.静态代码块
静态代码块:一个类中初始化块若有修饰符,则只能被static修饰,称为静态代码块,当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
//static块通常用于初始化static(类)属性
class Person{
public static int total;
static{
total = 100;//为total赋初始值
}
......//其他属性或方法声明
}
4.静态代码块与非静态代码块的区别
5.4关键字:final
在Java中证明类、属性和方法时,可使用final来修饰,表示“最终”。
(1)final标记的类不能被继承。
提高安全性,提高程序的可读性。如:String类、System类、StringBuffer类
(2)final标记的方法不能被子类重写。
如:Object类中各getClass( )。
(3)final标记的变量(成员变量或局部变量)即称为常量。
名称大写,且只能被赋值一次。如:final标记的成员变量必须在声明的同时或者每个构造方法中或代码块中显式赋值,然后才能使用。常量定义名称约定使用大写,如果多个单词组成名称,用_连接。
如:final double PI=3.14; final NAME_1 = “Sam”;
5.5抽象类(abstract class)
1.关于抽象类
随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计硬要保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于他没有具体的实例,这样的类叫做抽象类。
2.抽象类举例
public abstract class Animal{
public abstract void text();//只要类中有一个抽象方法,类就必须是一个抽象类
public abstract void move();
}
class Dog extends Animal{
@Override
public void text() {
}
@Override
public void move() {
System.out.println("狗的移动方法是跑");
}
}
class Fish extends Animal{
@Override
public void text() {
}
@Override
public void move() {
System.out.println("鱼的移动方法是游");
}
}
3.抽象类应用
解决方案
Java允许类设计者指定:超类声明一个方法但不提供实现,该方法的实现由子类提供。这样的方法称为抽象方法。有一个或更多抽象方法的类称为抽象类。
Vehicle是一个抽象类,有两个抽象方法
public abstract class Vehicle{
//计算燃料效率的抽象方法
public abstract double calcFuelEfficiency();
//计算行驶距离的抽象方法
public abstract double calcTripDistance();
}
public class Truck extends Vehicle{
public double calcFuelEfficiency(){//写出计算卡车的燃料效率的具体方法}
public double calcTripDistance(){//写出计算卡车行驶距离的具体方法}
}
public class RiverBarge extends Vehicle{
public double calcFuelEfficiency(){//写出计算驳船的燃料效率的具体方法}
public double calcTripDistance(){//写出计算驳船行驶距离的具体方法}
}
//注意:抽象类不能实例化 new Vehicle()是非法的
4.抽象类问题
(1)为什么抽象类不仅可以使用final声明?
抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写弗雷德抽象方法,并提供方法体
(2)一个抽象类中可以定义构造器吗?
抽象类可以有构造方法,只是不能直接船舰抽象类的实例对象而已。
抽象类不能实例化 new Vehicle()是非法的
5.模板方法设计模式(TemplateMethod)
public abstract class Template{
public final void getTime(){
long start = System.currentTimeMills();
code();
long end = System.currentTimeMills();
System.out.println("执行时间是:" + (end - start));
}
public abstract void code();
}
class SubTemplate extends Template{
//计算循环10000次的时间
public void code(){
for(int i = 0; i < 10000; i++){
System.out.println(i);
}
}
}
//Text类测试
public class Text{
public static void main(String args[]){
SubTemplate t = new SubTemplate();
t.getTime();
}
}
5.6接口
1.关于接口
2.接口的特点
举例:
3.接口注意点
4.接口例题
用Java描述一个老师即会唱歌也会做菜
(1)分析
(2)创建类和接口并写出相关内容
//Person抽象类
public abstract class Person {
int age;
String name;
int sex;
abstract void showInfo();
}
//SCTeacher类
/**
* 这个是描述会唱歌的厨师是一个老师的类
* @author 13088
*
*/
public class SCTeacher extends Person implements Cooking,Sing{
String course;//教的科目
public void setInfo(){
super.age = 30;
super.name = "Sam";
super.sex = 0;//0man 1woman
this.course = "数学";
}
@Override
void showInfo() {
System.out.println("会唱歌的厨师的老师的信息是:");
System.out.println(super.age);
System.out.println(super.name);
System.out.println(super.sex);
System.out.println(this.course);
}
@Override
public void singing() {
System.out.println(super.name + "老师擅长英文摇滚");
}
@Override
public void fry() {
System.out.println(super.name + "老师拿手的厨艺是炒菜");
}
}
//Cooking接口
/**
* 做饭的接口
* @author 13088
*
*/
public interface Cooking {
void fry();
}
//Sing接口
/**
* 唱歌的接口
* @author 13088
*
*/
public interface Sing {
void singing();
}
//Text类
public class Text {
public static void main(String[] args) {
SCTeacher sct = new SCTeacher();
sct.setInfo();
sct.showInfo();
sct.fry();
sct.singing();
}
}
(3)最终运行得:
5.工厂方法(FactoryMethod)
(1)什么是工厂方法
(2)工厂方法举例
宝马车的生产,有BMW产品接口,BMWFactory汽车生产工厂接口,Text测试类
package 第五章.ImportExample;
/**
* 宝马车的产品接口
* @author 13088
*
*/
public interface BMW {
//产品的信息介绍
//车的发动方式
void showInfo();
}
/**
* 构建具体的车的类
* @author 13088
*
*/
class BMW3i implements BMW{
@Override
public void showInfo() {
System.out.println("这个是宝马3系车");
}
}
class BMW5 implements BMW{
@Override
public void showInfo() {
System.out.println("这个是宝马5系车");
}
}
class BMW7 implements BMW{
@Override
public void showInfo() {
System.out.println("这个是宝马7系车");
}
}
package 第五章.ImportExample;
/**
* 宝马车生产工厂的接口
* @author 13088
*
*/
public interface BMWFactory {
BMW productBMW();
}
/**
* 实现具体的车型的生产工厂
* @author 13088
*
*/
class BMW3Factory implements BMWFactory{
@Override
public BMW productBMW() {
System.out.println("生产宝马3系车");
System.out.println("改造宝马3系车,更名为BMW3i");
return new BMW3i();
}
}
class BMW5Factory implements BMWFactory{
@Override
public BMW productBMW() {
System.out.println("生产宝马5系车");
return new BMW5();
}
}
class BMW7Factory implements BMWFactory{
@Override
public BMW productBMW() {
System.out.println("生产宝马7系车");
return new BMW7();
}
}
package 第五章.ImportExample;
public class Text2 {
public static void main(String[] args) {
BMW b3 = new BMW3Factory().productBMW();
b3.showInfo();
BMW b5 = new BMW5Factory().productBMW();
b5.showInfo();
BMW b7 = new BMW7Factory().productBMW();
b7.showInfo();
}
}
运行结果:
其中工作人员A执行BMW接口与BMWFactory接口的工作,工作人员B执行Text方法。工厂方法能够实现:工作人员A修改代码不影响工作人员B的工作。
5.7内部类
1.关于内部类
public class Text2 {
int i;
public int j;
private int l;
//内部类A
class A{
public void setText2Fileds(){
Text2.this.i = 1;
Text2.this.j = 2;
Text2.this.l =3;
}
}
//设置信息 外部类要使用内部类的方法,需要先new内部类的对象
public void setInfo() {
new A().setText2Fileds();
}
//获取信息
public void getInfo() {
System.out.println(this.i);
System.out.println(this.j);
System.out.println(this.l);
}
public static void main(String[] args) {
Text2 t2 = new Text2();
t2.setInfo();
t2.getInfo();
}
}
2.内部类特性
面向对象内容总结
第六章 异常处理
6.1 Java异常
1.关于异常
2.异常举例
(1)数组越界
package 第六章;
public class Test {
public static void main(String[] args) {
String[] strs = new String[] {"a","b","c"};
for(int i = 0; i < 4; i++) {//0,1,2,3,strs没有第四个元素,这时要输出strs[3]就没有
//java.lang.ArrayIndexOutOfBoundsException数组越界
System.out.println(strs[i]);
}
}
}
运行结果:
(2)空指针
public class Test {
public static void main(String[] args) {
A a = null;
//java.lang.NullPointerException空指针异常
System.out.println(a.i);
}
}
class A{
int i;
}
运行结果:
(3)错误运算
如任何数除以零不存在
package 第六章;
public class Test {
public static void main(String[] args) {
int a = 0;
//java.lang.ArithmeticException运算错误
System.out.println(2/a);
}
运行结果:
3.常见异常
RuntimeException
(1)错误的类型转换
(2)数组下标越界
(3)空指针访问
IOException
(1)从一个不存在的文件中读取数据
(2)越过文件结尾继续读取EOFException
(3)连接一个不存在的URL
6.2异常处理
1.异常处理机制
2.捕获异常
//异常处理通过 try-catch-finally 语句实现的
try{//用try{}来括住一段有可能出现异常的代码段
}catch(ExceptionName1 e){//当产生ExceptionName1型异常时的处置措施
//当不知道捕获的是什么类型的异常时,可以直接使用所有异常的父类Exception
}catch(ExceptionName2 e){//当产生ExceptionName2型异常时的处置措施
}finally{//finally可写可不写,它是捕获异常体系中最终一段会执行的部分
}
关于捕获异常
3.抛出异常
(1)声明抛出异常
举例
package 第六章;
public class Test1 {
public static void main(String[] args) throws Exception {//可以在main方法继续抛出异常
//main方法抛出异常到虚拟机上去,在程序中不能处理
B b = new B();
// try{//throws在代码这抛出的异常,在调用方去捕获处理
// b.test();
// }catch(Exception e) {
// e.printStackTrace();
// }
b.test();
}
}
class B{
int i;
public void test() throws Exception{//可以使用throws在代码这抛出异常,在调用方捕获处理
B b = null;
System.out.println(b.i);
}
}
(2)重写方法声明抛出异常的原则
重写方法不能抛出比被重写方法范围更大的异常类型
子类重写父类的方法时,子类不能抛出比父类方法范围更大的异常
class B{
int i;
//NullPointerException的父类是Exception
public void test() throws NullPointerException{//可以使用throws在代码这抛出异常,在调用方捕获处理
B b = null;
System.out.println(b.i);
}
}
class C extends B{
@Override
public void test() throws NullPointerException {
//不能抛出Exception,子类C抛出的异常不能比父类B的异常NullPointerException范围更大
super.test();
}
}
(3)人工抛出异常
public class Test1 {
public static void main(String[] args){
B b = new B();
try {
b.test1(-100);
} catch (Exception e) {
e.printStackTrace();
}
}
class B{
int i;
//NullPointerException的父类是Exception
public void test() throws NullPointerException{//可以使用throws在代码这抛出异常,在调用方捕获处理
B b = null;
System.out.println(b.i);
}
int age;
public void test1(int age) throws Exception{
if(age >=0 && age <= 150) {
System.out.println("年龄是:" + this.age);
}else{
throw new Exception("这个年龄不在0~150之间");
}
}
}
运行结果:
4.创建用户自定义异常类
Java提供的异常的类一般是够用的,只有特殊的情况可能需要自己编写异常类,情况很少见