1、继承
概述:
提高了代码的复用性,让类与类之间产生关系,有了这个关系,才有了多态的特性。
注意:千万不要未来获取其他类的功能,简化代码而继承,必须是类与类之间有所属关系才可以
Java语言中只支持单继承,不支持多继承。
原因:因为多继承容易带来安全隐患,当多个父类定义相同的功能,当功能内容不同时,子类不确定运行哪一个。但是Java保留这种机制,并用另一种体现形式来完成表示叫多实现
特点:
当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容
,如同父类函数被覆盖一样。这种情况叫做重写。
(子类虽具备该功能,但是功能内容却和父类不一致。这时候没有必要定义新功能,而是使用覆盖的特性,保留父类的功能定义,并重写功能内容)
注意:子类覆盖父类,必须保证子类权限大于父类,否则编译失败,静态只能覆盖静态。
子类中的构造函数:
在子类对象进行初始化时,父类的构造函数也会运行。因为子类的构造函数默认第一行有一条隐式语句super()。(因为父类的数据再累可以直接获取,所以子类对象建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对象初始化时,要先访问以下父类的构造函数),如果要访问父类中指定的构造函数,可以通过手动定义super语句来指定。
2、final关键字
Final可以修饰的内容:类、方法、变量
Final修饰的特点:
修饰的类不能被继承,修饰的方法不能被覆盖,修饰的变量,只能被赋值一次
Final的用途:
当在秒描述事物时,一些数据的值是固定的,那么为了增加阅读性,都给这些值起个名字,方便阅读,而这个值不需要改变,所以加final修饰
3、抽象类
概述:
当多个类中出现相同的功能,但是功能主体不同,这时候可以进行向上抽取。只抽取功能定义,而不抽取功能主体,因而衍生出抽象类。
特点:
1、抽象方法一定在抽象类中
2、抽象类和抽象方法必须被abstract关键字修饰
3、抽象类不可以用new创建对象,以为调用抽象方法没意义
4、抽象类中的方法要被使用,必须由子类复写所有的抽象方法,建立子类对象调用,如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
5、抽象类比一般类多个抽象方法
6、抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
为什么需要抽象类:
该如何描述事物的功能,需要明确出现,但是无法定义主体所以通过抽象方法表示。
4、接口
概述:
初期可以理解为是一个特殊的抽象类,当抽象类中的方法都是抽象时,那么该类通过接口来表示,他的出现将多继承通过另一种方式体现出来叫做多实现,用interface定义。
格式特点:
常量:public static final
方法:public abstract
(这些实际情况下可以省略不写)
注意事项:
接口是不可以创建对象的,因为有抽象方法,需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。
继承与接口的关系
类↔类:可以继承,但不能多继承(extends)
类↔接口:实现 (implements),类中方法覆盖必须加public
接口↔接口:继承,也可以多继承,(extends)
特点:
1、接口是对外暴露原则
2、接口是程序功能的扩展
3、接口可以用来多实现
4、类与接口是实现关系,而且类可以继承一个类的同时实现多个接口。
5、接口与接口之间可以有继承关系
5、多态
定义:
某一类事物的多种存在状态,也可以理解为事物存在多种体现形态
体现:
父类的引用指向了自己的子类对象,父类的引用也可以接收自己的子类对象
前提:
必须类与类之间有联系,要么继承,要么实现,通常还需要存在覆盖
好处:
多态的出现大大调高了程序的扩展性
弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员
类型转换:
父类的引用指向了自己的子类对象时,这引用可以被提升,也可以被强制转换,多态自始至终是子类对象在做着变化。
多态中成员非静态函数的特点:
编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有编译通过,没有,编译失败。
运行期间:参阅对象所属的类中是否有调用的方法
总结:成员函数在多态调用时,编译看左边,运行看右边
多态中成员变量的特点:
无论编译运行都参考左边(引用型变量)
静态成员函数特点:
无论编译运行都参考左边
练习代码:
1、多态主板示例
package DuoTai;
interface PCI
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System.out.println("主板开了!!!");
}
public void usePCI(PCI p)
{
p.open();
p.close();
}
}
class Network implements PCI
{
public void open()
{
System.out.println("网络开");
}
public void close()
{
System.out.println("网络关");
}
}
public class ZhuBan
{
public static void main(String[]args)
{
MainBoard s=new MainBoard();
s.run();
s.usePCI(new Network());
}
}
2、计时器的使用
package test6;
public class test {
public static void getTime()
{
int s=0;
long start = System.currentTimeMillis();
for(int i = 0;i<100000;i++)
{
System.out.println(i+" ");
}
long end=System.currentTimeMillis();
long time= end-start;
System.out.println("Time:"+time+"毫秒");
}
public static void main(String args[])
{
getTime();
}
}
6、内部类
概述:
讲一个类定义在另一个类的里面,对里面的类称为内部类(内置类、嵌套类)
访问特点:
内部类既可以直接访问外部类的成员,包括私有成员,而外部类要访问内部类中的成员必须建立内部类的对象
原因:之所以可以直接访问外部类中的成员,是因为内部类持有一个外部类的引用
格式:外部类名.this
静态内部类与成员内部类:
当内部类定义在外部类成员位置时,而且非私有可以在外部其他类中,可以直接建立内部类对象。
外部类名。内部类名 变量名=外部类对象。内部类对象
Outer.Inner.in=new Outer().new Inner();
当内部类在成员位置时,就可以被成员修饰符所修饰。
Private:将内部类在外部类中进行封装
Static:内部类就具备静态特性
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
注意:当内部类中定义静态成员,该内部类必须是static,当外部类中的静态方法访问内部类时,内部类必须是静态的。
局部内部类:
当内部类定义成局部时
1、不可以被成员修饰符修饰
2、可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问他所在的局部中的变量,只能访问被final修饰的局部变量
定义原则:
当描述事物时,事物的内部还有事物,该事物用内部类描述,因为内部事物在使用外部事物。
练习代码:
package days2;
class Outer
{
int x=3;
void method()
{
Inner in=new Inner();
System.out.println("外部类x="+x);
in.function();
}
class Inner
{
int x=4;
void function()
{
System.out.println("内部类x="+x);//执行的是内部类x
System.out.println("内部类x="+Outer.this.x);//内部类中执行外部类中的x
}
}
}
class Inner
{
public static void main(String args[])
{
Outer out=new Outer();
out.method();
Outer.Inner in=new Outer().new Inner();
in.function();//这样访问内部类和外部类的x都访问到了
}
}
7、匿名内部类
概述:
匿名内部类其实就是内部类的简写格式,定义内部类的前提是内部类必须继承一个类或实现接口
格式:
New 父类或者接口(){定义子类内容}
实质:
其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解为带内容的对象。
注意:匿名内部类定义的方法最好不要超过3个
练习代码:
package days2;
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
int x=4;
void function()
{
AbsDemo t=new AbsDemo()
{
int x=5;
void show()
{
System.out.println("x="+x);
}
};
t.show();
}
}
class NiMing
{
public static void main(String[] args)
{
new Outer().function();
}
}
package days2;
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
static void function()
{
System.out.println("木头人");
}
static class Inner extends AbsDemo
{
public void show()
{
System.out.println("method run");
}
};
}
class NiMing
{
public static void main(String[] args)
{
new Outer.Inner().show();
new Outer().function();
}
}
8、异常
概述:
异常:程序在运行时出现不正常情况
异常由来:问题也是现实生活中一个具体的事物,也可以通过java类的形式进行描述,并封装对象,其实就是java对不正常情况进行描述后的对象的体现
对于问题的划分
——严重问题:java通过Error类进行描述(对于Error,一般不编写针对 性代码进行处理)
——非严重问题:通过Exception类进行描述(对于Exception,使用针对性的处理方式进行处理)
无论Error或者Exception都具有一些共性内容
比如不正常情况的信息,引发原因等。
Try-catch
异常处理java提供特有的语句进行处理
Try
{
需要被检测的代码
}
Catch(异常类 变量)
{
处理异常的代码
}
Finally
{
一定会执行的语句
}
练习代码:
package days2;
public class Exception1
{
public static void main(String[]args)
{
try{
int x=4/0;
}
catch(Exception e)
{
System.out.println("除零了!!!");
System.out.println(e.toString());//获取异常信息
System.out.println(e.getMessage());//异常名称、异常信息
e.printStackTrace();//异常名称、异常信息、异常出现位置
}
}
Throws ;在功能上通过throws关键字声明该功能有可能会出现问题
对多异常的处理
1、声明异常时建议声明更为具体的异常,这样处理更具体
2、对方声明几个异常,就应对应几个catch块处理,如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面
3、建立在进行catch处理时,catch中一定要定义具体处理方式,不要简单定义一句e.printStackTrace(),也不要简写为一条输出语句
自定义异常
因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。所以对于这些特有的问题,进行自定义的异常封装,自定义异常必须是自定义类继承Exception
继承Exception的原因:异常体系的特点,因为异常类和异常对象都被抛出,他们都具备可抛性,这个可抛性是Throwable这个体系的独有特权,只有这个体系的类和对象才可以被throw和throws操作
定义自定义异常信息:
因为父类已经把异常信息的操作都完成了,所以子类只要把异常信息传递给父类,通过super语句,那么就可以通过getMessage()方法获取自定义信息
练习代码:
package days2;
class FushuException extends Exception
{
private String msg;
FushuException(String msg)
{
this.msg=msg;
}
public String getMessage()
{
return msg;
}
}
class Jisuan
{
float div(int a,int b) throws FushuException
{
if(b==0)
throw new FushuException("除数不能为零");
return a/b;
}
}
public class Exception2
{
public static void main (String[]args)
{
Jisuan s=new Jisuan();
try
{
float x=s.div(4, 0);
}
catch(FushuException e)
{
System.out.println(e.toString());
}
}
}
Throw和throws的区别
Throw:使用在函数内,后面是异常对象
Throws:使用在函数上,后面的异常类可以跟多个,用逗号隔开
Runtime Exception
Exception中有一个特殊的子类异常RuntimeException(运行时异常)
如果在函数内抛出该异常,函数上可以不用声明,编译一样通过
如果在函数上声明该异常,调用者可以不用进行处理,编译一样通过
之所以不用在函数上声明是因为不需要让调用者进行处理。当该异常发生时,希望程序停止,因为在运行时出现了无法继续运算的情况,希望停止程序后,由程序员对代码进行修正
自定义异常时,如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException
对于异常分两种
编译时被检测异常
编译时不被检测异常(运行时异常,RuntimeException及其子类)
练习代码:
package days2;
class FushuException2 extends RuntimeException
{
private String msg;
FushuException2(String msg)
{
super(msg);
}
}
class Jisuan2
{
float div(int a,int b) throws FushuException2
{
if(b==0)
throw new FushuException2("除数不能为零");
return a/b;
}
}
public class Exception3
{
public static void main (String[]args)
{
Jisuan2 s=new Jisuan2();
try
{
float x=s.div(4, 0);
}
catch(FushuException2 e)
{
System.out.println(e.toString());
}
}
}
需求
开始思考上课中出现的问题。
比如问题是:电脑蓝屏,电脑冒烟。
要对问题进行描述,封装成对象。
可是当冒烟发生后,出现讲课进度无法继续。
出现了讲师的问题:课时计划无法完成。
package days2;
class LanPingException extends Exception
{
LanPingException(String msg)
{
super(msg);
}
}
class MaoYanException extends Exception
{
MaoYanException(String msg)
{
super(msg);
}
}
class Computer
{
private static int state=3;
public void run()throws MaoYanException,LanPingException
{
if(state==1)
throw new LanPingException("电脑蓝屏了");
if(state==2)
throw new MaoYanException("电脑冒烟了");
System.out.println("电脑正常运行");
}
public void reset()
{
System.out.println("电脑重启!!!");
}
}
class Teacher
{
private Computer std;
private String name;
Teacher(String name)
{
this.name=name;
std = new Computer();
}
public void perlect() throws MaoYanException
{
try
{
std.run();
}
catch(LanPingException e)
{
std.reset();
}
catch(MaoYanException e)
{
System.out.println("冒烟了,没救了!!!");
}
}
}
public class Exceptiontest
{
public static void main(String[]args) throws MaoYanException
{
Teacher tea=new Teacher("毕老师");
tea.perlect();
}
}
异常处理语句的其他形式
1、try{ } catch{ }
2、Try{} catch{ } finally{ }
3、Try{ } finally{ }
Catch用于处理异常,如果没有catch就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明。
异常在子父类覆盖的体现
1、子类在覆盖父类时,如果父类的方法抛出异常,那么子类覆盖的方法,只能抛出父类的异常或者没异常的子类
2、如果父类方法抛出多个异常,那么子类覆盖该方法时,只能抛出父类异常的子集。
3、如果父类或者接口中的方法没有异常抛出,那么子类在覆盖方法时也不可以抛出异常,如果子类方法发生异常,就必须要进行try处理。
有一个圆形和长方形。
都可以获取面积。对于面积如果出现非法的数值,视为是获取面积出现问题。
问题通过异常来表示。
现有对这个程序进行基本设计。
练习代码:
package day3;
interface Shape
{
void getArea();
}
class NoValueException extends Exception
{
String msg;
NoValueException(String msg)
{
super(msg);
}
}
class Rectangle implements Shape
{
private double a,b;
Rectangle(double a,double b) throws NoValueException
{
this.a=a;
this.b=b;
if(a<=0||b<=0)
throw new NoValueException("非法输入");
}
public void getArea()
{
System.out.println("矩形的面积是"+a*b);
}
}
class Circle implements Shape
{
double r;
private final double PI= 3.14;
Circle(double r) throws NoValueException
{
this.r=r;
if(r<=0)
throw new NoValueException("非法输入");
}
public void getArea()
{
System.out.println("圆的面积是"+PI*r*r) ;
}
}
public class Exercise
{
public static void main(String []args) throws NoValueException
{
Circle cir=new Circle(1);
Rectangle rec=new Rectangle(1.0,2.0);
cir.getArea();
rec.getArea();
}
}
异常总结:
异常是对问题的描述,将问题进行对象的封装
异常体系:Throwable分为Error和Exception(包含RuntimeException)
异常体系特点:异常体系中所有类以及建立的对象都具备可抛性,也就是说可以被throw和trows关键字所操作,只有异常体系才具备这个特点
Throw和throws的用法
Throw:定义在函数内,用于抛出异常
Throws:定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开
当函数内有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败。
注意:RuntimeException除外,函数内部如果抛出RuntimeException异常,函数上可以不用声明。如果函数声明异常,函数上可以不用声明。如果函数声明异常,调用者需要进行处理,处理方法可以throws也可以try。
异常有两种:
编译时异常:该异常在编译时,如果没有处理(没有抛出也没有try),编译失败,该异常被标识,可以被处理。
运行时异常(编译不检测):在编译时,不需要处理,编译器不检查,该异常发生建议不处理,让程序停止,对代码进行修正。
异常处理语句:try{ 需要被检测代码} catch(){处理异常代码} finally{一定会执行代码}
有三种结合方式:
1、try{ } catch(){ }
2、Try{ } finally{ }
3、Try{ } catch{ } finally{ }
注意:finally (1)定义的通常是关闭资源代码 因为资源必须释放
(2) System.exit(0) 系统退出,读不出finally,不会被执行
自定义异常:
1、定义类继承Exceptions或者RuntimeExceptions,为了让该自定义类具备可抛性
2、让该类具备操作异常的共性方法。当要定义自定义异常信息时,可以用父类定义好的功能
自定义异常的好处:
1、将问题进行封装
2、将正常该程序代码和问题处理代码相分离,方便阅读
异常处理原则:
1、处理方式:try和throw
2、调用到抛出异常功能时,抛出几个就处理几个
3、一个try对应多个catch,多个catch的父类的catch放到最下面
4、Catch需要定义针对性的处理方式,不要简单定义printStackTrace输出语句,也不要不写
5、为捕获异常,本功能处理不了时,可以继续在catch中抛出
6、如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,再抛出和该功能相关的异常
7、或者异常可以处理,当需要将异常产生和本功能相关问题提供出去,让调用者知道并处理,也可以将捕获的异常处理后,转换新的异常
异常注意事项
1、子类抛出的异常必须是父类异常的子类或子集
2、如果父类或者接口没有异常抛出,子类覆盖出现异常只能try不能throw
9、包(package)
概述:
对类文件进行分类管理,给类提供多层命名空间,写在程序文件第一行
包与包之间的访问
被访问的包中的类以及类中的成员,需要public修饰,不同包中的子类可以直接访问父类中被protected权限修饰的成员
包与包之间可以使用的权限:public、protected
10、导入import
Import,导入包中的类,加上.*,是导入该包所有的类,
建议定义包名,不要重复,可以使用url来定义,url是惟一的。
11、jar包
方便项目的携带,方便于使用,只要在classpath设置jar路径即可,数据库驱动,SSH框架等都是以jar包体现的