-----------android培训、java培训、java学习型技术博客、期待与您交流!-----------
Java的继承
1.继承的概述
继承:
1.提高了代码的复用性。
2.让类与类之间产生了关系。有了这个关系,才有了多态的特性。
注意:千万不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。所以关系is a.
java 语言中:java只支持单继承,不支持多继承。
当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。
因为多继承容易带来安全隐患。
但是java保留了这种机制。并用另一种体现形式来完成表现。多实现。
java支持多层继承。也就是一个继承体系
如何使用一个继承体系中的功能呢?
想要使用体系,先查询体系父类的描述。因为父类中定义的是该体系*性的功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经可以基本使用了。
那么在具体实现时,要创建子类的对象,为什么呢?
一是因为有可能父类不能创建对象。
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
简单一句话:查阅父类功能,创建子类对象使用功能。
大家记住:java中一个孩子只有一个父亲,不允许有多个父亲。
子父类出现以后,类成员的特点:
类中成员:
1.变量。
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this。
子类要访问父类中的同名变量,用super。
super的使用和this的使用几乎一致。
super代表的是父类对象的引用。
2.子父类中函数。
当子类出现和父类一模一样的函数时,
当子类调用该函数,会运行子类函数的内容。
这种情况是函数的另一个特性:重写(覆盖)。
当子类继承了父类,沿袭了父类的功能,到子类中,
但是子类虽具备该功能,但是功能内容却和父类不一致,
这时,没有必要定义新功能,而是使用覆盖的特性,
保留父类的功能定义,并重写功能内容。
覆盖:
1.子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2.静态只能覆盖静态。
记住大家:
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。包括返回值类型。
3.子父类中构造函数。
3.子父类中的构造函数。
在对子类对象进行初始化时,父类的构造函数也会运行。
那是因为子类的构造函数默认的第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
注意:super语句一定定义在子类构造函数的第一行。
子类的实例化过程.
结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定访问父类中的构造函数。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。
为什么super构造函数 和this构造函数不能同时定义在一行?
答:因为他们都必须写在第一行。
为什么要写第一行?
因为初始化动作要做。
final关键字
final关键字
final :最终。作为一个修饰符。
1.final可以修饰类,方法,变量。
2.final修饰的类不可以被继承。为了避免被继承,被子类复写功能。
3.被final修饰的方法不可以被复写。
4.被final修饰的变量是一个常量。只能被赋值一次。既可以修饰成员变量。又可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值其个名字。方便阅读。
而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所以字母都大写,如果有多个单词组成。
单词间通过_连接。
5.内部类定义在类中的局部位置上,只能访问局部被final修饰的局部变量。
抽象类
当多个类中出现相同功能,但是功能主体不同。
这时可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体。
抽象:看不懂
抽象类的特点:
1.抽象方法一定在抽象类中。
2.抽象方法和抽象类都必须被abstract关键字修饰。
3.抽象类不可以用new创建对象。因为调用抽象方法没有意义。
4.抽象类中的抽象方法要被使用,必须有子类复写其所有的抽象方法后,建立子类对象调用。
如果子类覆盖部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物只不过,该事物出现了一些看不懂的东西。
这些不确定的东西,也就是该事物的功能,需要明确出现,但是无法定义主体。
通过抽象方法来表示。
抽象类比一般类多了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
模板设计方式:
需求:获取一段程序运行的时间。
原理后期程序开始和结束的时间并相减即可。
获取时间:system.currentTimeMills(); current卡润特
当代码完成优化后,就可以解决这类问题。
这就是模板设计方式。
什么是模板方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分。
那么这时就将不确定的部分暴露出去。由子类去完成。
接口:
接口:初期理解,可以认为是一个特殊的抽象类。
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
class :用于定义类
interface:用于定义接口。
接口定义时,格式特点:
1.接口中常见的定义:常量,抽象方法。
2.接口中的成员都有固定修饰符。
常量:public static final
方法: public abstract
记住:接口中的成员都是public修饰的。
接口:是不可以创建对象的,因为有抽象方法。
需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类可以实例化。
否则子类是一个抽象类。
接口可以被类多实现,,也是对多继承不支持的转换形式。java支持多实现。
implements 实现。
接口的特点:
1.接口是对外暴露的规则。
2.接口是程序功能扩展。
3.接口可以用来多实现。
4.类与接口直接是实现关系,而且类可以继承一个类的同时实现多个接口。
5.接口与接口直接可以是继承的关系。
降低偶合性。
多态
多态:可以理解为事物存在的多种体现形态。
1.多态的体现:
父类的引用指向自己的子类对象。
父类的引用可以接收自己的子类对象。
instanceof:实例 关键字
2.多态的前提:
必须是类与类之间有关系。要么继承,要么实现。通常还有一个前提:存在覆盖。
3.多态的好处:
多态的出现大大提高程序的扩展性。
通常还有一个前提:存在覆盖。
4.多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5.多态的应用:
Animal a=new Cat();//类型提升,向上转型。把猫提升为了动物。
//如果想要调用猫的特有方法是,如何操作?
//强制将父类的引用转成子类类型,向下转型。
Cat c = (cat)a;
c.catchMouse();
/*
千万不要出现这样的操作,就是将父类的对象转成子类对象。
我们能转换的是父类的引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。
多态自始至终都是子类对象在做着变化。
//Animal a = new Animal();这样做是错误的,千万不要出现这样的操作,就是将父类的对象转成子类对象。
//Cat c = (cat)a;
*/
6.多态的出现代码中的特点(多态使用的注意事项)
在多态中成员函数的特点(父类引用指向自己的子类):
在编译时期:参阅引用类型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边。
Object:是所有对象的直接或者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。equals:比较对象的地址值。
如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己的特有比较内容即可。这就是覆盖。
内部类:
1.内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有一个外部类的引用,格式:外部类名.this
2.外部类要访问内部类,必须建立内部类对象。
类能不能被私有修饰?
答:可以,内部类可以被私有修饰。当内部类在外部类的成员位置时,可以。
访问格式:
1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式 :外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in =new Outer().new Inner();
2.当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就是具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.funtion();
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事物在使用外部事物的内容。
内部类定义在局部时,
1.不可以被成员修饰符修饰。
2.可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
匿名内部类:
1.匿名内部类其实就是内部类的简写格式。
2.定义匿名颞部类的前提:
内部类必须是继承一个类或者实现接口。
3.匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4.其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。可以理解为带内容的对象。
5.匿名内部类中定义的方法最好不要超过3个。
异常处理机制
异常:就是程序在运行时出现不正常情况。
java在设计异常体系时,将容易出现情况都封装成了对象。
异常的由来:问题也是现实生活中一个具体的事物,也是通过java的类的形式进行描述。并封装成对象。
其实就是java对不正常情况进行描述后的对象体现。
对于严重的,java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。
对与非严重的,java同Exception类进行描述。
对与Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容。
比如不正常的情况信息,引发原因等。
Throwable
|------Error
|------Exception
2.异常的处理:
一般处理:
try
{
需要被检测的代码
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定执行的语句;
}
3.对捕获的异常对象进行常见方法的操作。
String getmessage():获取异常信息.
在函数上声明异常。
便于提高安全性,让调用者进行处理。不处理编译失败。
对异常的处理:
1.声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
2.对方声明了几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
建立在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句e.printStackTrace().
也不要简单的就书写一条输出语句。
因为项目中会出现特有的问题,
而这些问题并未被java所描述并封装对象。
所以对于这些特有的问题可以按照java对问题封装的思想。
将特有问题,进行自定义的异常封装。
自定义异常:
需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的。
那么需要对这个问题进行自定义的描述。
当在函数内部出现了throw抛出异常对象,那么就必须要给出对应的处理动作。
要么在内部try catch处理。
要么在函数上声明让调用者处理。
一般情况下,函数出现异常,函数上需要声明出来。
发现打印出的结果中只有异常的名称,却没有异常的信息。
因为自定义的异常并未定义信息。
如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息传递给父类通过super语句。
那么就可以直接同getMessage方法获取自定义的异常信息。
自定义异常:
必须是自定义类继承Exception.
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具可抛性。这个可抛性是Throwable这给体系中独有的特性。
只有这个体系的类和对象才可以被throws 和throw 操作。
只有这个体系中的类和对象才可以被throws和throw操作。
throws和throw的区别
throws使用在函数上。
throw使用在函数内。
throws后面跟的异常类。可以是多个。用逗号隔开。
throw后面跟的是异常对象。
Exception中有一个特殊的子类异常RuntimeException运行时异常。
如果在函数内部抛出该异常,函数上可以不声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过。
之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运行的情况,希望停止程序后,对代码进行修正。
自定义异常时:如果该异常的发生,无法再继续进行运算。
就让自定义异常继承RuntimeExcepton.
对于异常分两种:
1.编译时被检测的异常。(编译时异常。Exception以及他的子类必须在函数上声明。是可以处理的异常。
2.要么抛异常,要么try catch处理)
2.编译时不被检测的异常(运行时异常。RuntimeException以及其子类)
3.finally代码块:定义一定执行的代码。
4.通常用于关闭资源。
第一个格式:
try{} catch(){}
第二个格式:
try{} catch(){} finally{}
第三个格式:
try{] finally{}
记住一点:catch是用于处理异常。如果没有catch就代表异常没有被处理过,
如果该异常时检测是异常。那么必须声明。
异常在子父类覆盖中的体现。
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者改异常的子类。
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生异常,就必须进行try处理。绝对不能抛。
----------------------------------------------
异常:
异常是什么?是对问题的描述。将问题进行对象的封装。
异常体系:
Throwable
|---Error
|---Exception
|----RuntimeException
异常体系的特点:异常体系中所有类以及建立的对象都具备可抛性。
也就是说可以被throw和throws关键字所操作。
只有异常体系具备这个特点。
throw 和 throws 的用法:
throw 定义在函数内,用于抛出异常对象。
throws 定义在函数上,用于抛出异常类,用逗号隔开。
当函数内容有 throw 抛出异常对象,并未进行try处理,必须要在函数上什么,都在编译失败。
注意: RuntimeException 除外。也就是说,函数内如果抛出异常 RuntimeException 异常,函数上可以不用声明。
如果函数声明了异常,调用者需要进行处理。处理方式可以 throws 和try。
-----------------------------------------
异常有两种:
编译时被检测异常:
该异常在编译时,如果没有处理(没有抛出也没有try),编译失败。
该异常被标识,代表这可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
异常处理语句:
try
{
需要被检测的代码;
}
catch ()
{
处理异常的代码;
}
finally
{
一定会处理的代码;
}
有三个结合格式:
第一种格式: 第二种格式 第三种格式
try try try
{ { {
} } }
catch () finally catch()
{ { {
} } }
finally
}
{
注意; {
1.finally 中定义的通常是关闭资源代码, 因为资源必须被释放。
2.finally 只有一种情况不会执行。当执行到 System.exit(0); finally 不会执行。
----------------------------------------------------------
自定义异常:
定义继承 Exception 或者 RuntimeException
1.为了让自定义类具备可抛性。
2.让该类具备操作异常的共性方法。
当要定义异常的信息是,可以使用父类已经定义好的功能。
自定义异常信息传递给父类的构造函数。
class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}
自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。
-----------------------------------------
异常的好处:
1.将问题进行封装。
2.将正常流程代码和问题代码相分离,方便于阅读。
异常的处理原则:
1.处理方式有两种 try 或者 throws.
2.调用到抛出异常的功能时,抛出几个,就处理几个。
一个 try 对应 多个catch.
3.多个 catch ,父类的 catch 放到最下面。
4.catch 内,需要第一针对性的处理方式。不要简单定义printStackTrace 输出语句。
也不要不写。
当捕获到的异常,本功能处理不了时,可以继续在 catch 中抛出。
try
{
throw new AExcrption();
}
catch (AException e)
{
throw e;
}
如果该异常处理不了,但是不属于该功能出现的异常。
可以将异常转换后,在抛出和该功能相关的异常。
或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去。
当调用者知道。并处理。也可以将不会异常处理后,转换新的异常。
try
{
throw new AException();
}
catch (AEexception e)
{
//对AException处理。
throw new BException();
}
比如,汇款的例子。
异常的注意事项:
在子父类覆盖时:
1.子类抛出的异常必须是父类的异常的子类或者子集。
2.如果父类后者接口没有异常抛出是,子类覆盖出现异常,只能 try 不能抛。
参阅:
ExceptionTest.java 老师用电脑上课。
ExceptionTest.java 图像面积。
包(package)
1、对类文件进行分类管理
2、给类提供多层命名空间
3、写在程序的第一行
4、类名的全称是 包名.类名
5、包也是一种封装形式
6、Javac -d . 类名.Java