抽象类概述
定义没有方法体的方法,该方法的具体实现方式由子类完成,该方法就称为抽象方法,包含抽象方法的类叫抽象类。
当多个对象都具备相同功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体。那么只有功能声明,没有功能主体的方法称为抽象方法。
抽象类的特点
抽象类或抽象方法都必须要用abstract关键字来修饰。
抽象类不可以被实例化,也就是不可以用new创建对象;
抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
模板方法设计模式
/*
需求:获取一段程序运行的时间。
原理:获取程序开始和结束的时间并相减即可。
获取时间:System.currentTimeMillis();
当代码完成优化后,就可以解决这类问题。
这种方式,模版方法设计模式。
什么是模版方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出去。由该类的子类去完成。
*/
abstractclass GetTime
{
public final void getTime()
{
long start =System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
public abstract void runcode();
}
classSubTime extends GetTime
{
public void runcode()
{
for(int x=0; x<4000; x++)
{
System.out.print(x);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
//GetTime gt = new GetTime();
SubTime gt = new SubTime();
gt.getTime();
}
}
接口的概述
格式:interface { }
接口中的成员修饰符是固定的
成员常量:public static final
成员方法:public abstract
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”
接口的特点
接口是对外暴露的规则
接口是程序的功能扩展
接口可以用来多实现
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口
接口与接口之间可以有继承关系
多态
定义:某一类事物的多种存在形态
体现:父类或者接口的引用指向或者接收自己的子类对象
作用:多态的存在提高了程序的扩展性和可维护性
前提:需要存在继承或者实现关系,要有覆盖操作
父类 引用名 = new 子类();//向上转型,类型提升
//如果想调用子类的特有方法时,需向下转型,强制将父类的引用转成子类类型:
子类 引用名 = (子类)父类引用;
//注意:千万不要将父类的对象转换成子类类型,我们能转的是父类的引用指向了自己的子类对象时,该引用可以被提升,也可以强制转换。
//多态自始至终都是子类对象在做着变化。
多态用instanceof判断类型时,不要将判断父类型放在前面。
多态的特点
成员函数:
在编译时:要查看引用变量所属的类中是否有所调用的成员
在运行时:要查看对象所属的类中是否有所调用的成员
编译看左边,运行看右边
成员变量:
无论编译和运行,都参考左边。
静态成员函数的特点:无论编译还是运行,都参考左边。
Object:是所有对象的直接或者间接父类,该类中定义的方法为所有对象都具备的功能。
JAVA中所有对象都具备比较性:equals(),底层也是用==来完成的
Object类中已经提供了对象的是否相同的比较方法,如果自定义类中也有比较相同的功能,没有必要重新定义。只要沿袭父类中的功能,建立自己特有的比较内容。这就是覆盖。
toString(); 方法:每个对象都有字符串的表达形式。默认是打印该对象的hash值。可以复写变成对象特有的toString方法。
Class c = 对象.getClass(); //类文件对象。可以获取类信息。
内部类
将一个类定义在另一个类的里面,对里面的那个类称为内部类
访问特点:
内部类可以直接访问外部类的成员,包括私有成员
之所以可以直接访问外部类的成员,是因为内部类中持有了一个外部类的引用。该引用写法是外部类名 . this
而外部类要访问内部类的成员必须要建立内部类的对象
访问格式:
当内部类定义在外部类的成员位置上,而且非私有,可以在外部其它类中直接建立内部类对象。
外部类 . 内部类 引用 = new 外部类(). new 内部类();
当内部类在成员位置上,就可以被成员修饰符所修饰。比如:
private :将内部类在外部类中进行封装。
static :内部类可以被静态修饰,内部类就具备static的特性。被static修饰的内部类,只能访问外部类中的静态成员。
在外部其它类中访问静态内部类的非静态成员:new 外部类 . 内部类( ) . 方法();
在外部其它类中访问静态内部类的静态成员:外部类 . 内部类 . 方法();
注意:当内部类中定义了静态成员,该内部类必须是静态的。
当外部类中的静态方法访问内部类时,内部类也必须是静态的。
为什么要定义内部类
当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。
内部类定义在局部位置上
不可以被成员修饰符修饰。
可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
匿名内部类
匿名内部类就是内部类的简化写法。
定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
格式为:
new 外部类名或者接口名(构造函数参数){
覆盖类或者接口中的代码,也可以自定义内容
}.方法();
简而言之:就是建立一个带内容的外部类或接口的子类匿名对象
匿名内部类中定义的方法最好不要超过2个。
当调用的方法的参数是一个接口时,当这个接口的方法小于3个时,可以用匿名内部类。
异常
异常的体系
Throwable:Error,Exception
Exception和Error的子类名都是以父类名为后缀的
Throwable中的方法:
getMessage():获取异常信息,返回字符串
toString() : 获取异常类名和异常信息,返回字符串
printStackTrace() : 获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void
printStackTrace(PrintStream s) : 通常用该方法将异常内容保存在日志文件中,以便查阅
十一. throws和 throw
throws用于标识函数暴露出的异常
throw用于抛出异常对象
throws和throw的区别:
throws用在函数上,后面跟异常类名
throw用在函数里,后面跟异常对象
十二. 异常处理:
try{
需要检测的代码;
}catch(异常类 变量){
异常的处理代码;
}finally{
一定执行的代码;
}
finally只有一种情况下不会执行,就是在之前执行了System.exit(0);
十三. 多异常处理
调用的方法中抛出几个异常,就应该有几个catch进行捕获。不要定义多余的catch块。建议在进行catch处理时,catch中一定要定义具体的处理方式。不要简单的定义一句e.printStackTrace();
十三. 自定义异常
自定义异常类继承Exception类或者其子类
通过构造方法定义异常信息
class DemoException extends Exception{
DemoException(Stringmessage){
super(message);
}
}
通过throw将自定义异常抛出
throw new 自定义异常类名();
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。要么在内部try catch处理。要么在函数上声明让调用者处理。一般情况下,函数内出现异常,函数上需要声明。
因为父类中已经把异常信息的操作已经完成了,所以子类只要在构造时,将异常信息传递给父类通过super语句。那么就可以直接通过getMessage()方法获取自定义的异常信息了。
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。他们都具备可抛性,这个可抛性是Throwable这个体系中独有特点。
只有这个体系中的类和对象才可以被throws和throw操作。
throws和throw的区别:
throws:使用在函数上。后面跟异常类,可以跟多个,用逗号隔开。
throw :使用在函数内。后面跟异常对象。
十四. 异常细节
Exception中有一个特殊的子类异常RunTimeException运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过,如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。
之所以不用在函数上声明,是因为不需要让调用者处理。当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。
自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RunTimeException
对于异常分为两种:
编译时被检测的异常。
编译时不被检测的异常(运行时异常。RunTimeException以及其子类)
格式1:
try{
}catch(){
}
格式2:
try{
}catch(){
}finally{
}
格式3:
try{
}finally{
}
//catch是用来处理异常,如果没有catch就挖根挨批凤有被处理过,如果该异常是检测时异常。那么必须声明。
异常在子父类覆盖中的体现:
子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
如果父类或者接口的方法中,没有异常抛出。那么子类在覆盖方法时也不可以抛出异常。如果子类方法发生了异常,就必须要进行try处理。绝对不能抛。
十五. 包(package)
包是一种封装形式
编译时加参数,如:javac –d . 类名
类名的全称:包名.类名
被访问的包中的类权限必须是public的。类中的成员权限:public和protected
protected是为其它包的子类提供的一种权限
权限
public protected default private
同类 Y Y Y Y
同包 Y Y Y
子类 Y Y
不同包 Y
一个类文件中只能有一个public修饰的类
导入包:import 包名.类名
如果要导入包下所有的类,即包名.*,但不包括子包中的类
当导入的包中,存在重名的类时。调用时用:包名.类名 的方法
十六. Jar包
需要执行jar包中的类时,把jar文件路径放至classpath环境变量中