类的继承
概念
类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的类被称为子类,现有类被称作父类。
class 父类{
}
class 子类 extends 父类{
}
子类需要使用 extends
关键字来实现对父类的继承。子类在继承父类的时候,会自动继承父类的成员。同样的,子类也可以定义自己的属性和方法。
注意事项
-
在java中,类只支持单继承,不允许多继承。
class A{} class B{} class C extends A,B{} //不合法的继承
-
多个类可以继承一个父类。
class A{} class B extends A{} class C extends A{}
-
在java中支持多层继承。
class A{} class B extends A{} class C extends B{}
-
在java中父类与子类只是一个相对的概念,成对出现。
-
在继承中,子类不能直接访问父类的私有成员。
方法重写
- 子类的方法的
参数,方法名称
,要和父类的方法的参数,方法名称完全一样。 - 子类方法的返回类型和父类方法返回类型是一样,或者是父类返回类型的子类。
- 子类方法不能缩小方法的访问权限。
名称 | 发生范围 | 方法名 | 形参列表 | 返回类型 | 修饰符 |
---|---|---|---|---|---|
重载 | 本类 | 必须一样 | 类型,个数或者顺序至少有一个不同 | 无要求 | 无要求 |
重写 | 父子类 | 必须一样 | 相同 | 子类方法的返回类型和父类方法返回类型是一样,或者是父类返回类型的子类。 | 子类方法不能缩小方法的访问权限。 |
<重写>
<重载>
super 关键字
super 关键字可以在子类中调用父类的普通属性、方法和构造方法
使用super关键字访问父类的成员变量和成员方法
格式如:
super.成员变量
super.成员方法(参数1,参数2....)
使用super关键字访问父类中指定的构造方法
格式如:
super(参数1,参数2)
注意
使用super()调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次。
final关键字
final 关键字可以声明 类、属性、方法 。
- 使用final修饰的类不能有子类。
- 使用final修饰的方法不能被子类重写。
- 使用final修饰的变量是常量,常量不可修改。
final关键字修饰类
被final关键字修饰后,该类不可以被继承。
final关键字修饰方法
当一个类的方法被final关键字修饰后,这个类的子类将不能重写该方法。
final关键字修饰常量
被final关键字修饰对变量会变为常量,常量只能在声明时被赋值一次,在后面的程序中其值不能被改变。
在使用final声明变量时,要求全部字母大写。
抽象类和接口
抽象类
当定义一个类时,常常需要定义一些成员方法在描述类的行为特征,但有时这些方法的实现方法是无法确定的,此时我们需要定义抽象方法来满足需求。
抽象方法
格式:
abstract 返回值类型 方法名称(参数)
抽象类
格式:
//定义抽象类Animal
abstract class Animal{
//定义抽象方法
abstract void shout();
}
定义规则
- 抽象方法的类必须是抽象类
- 抽象类和抽象方法都要使用abstract关键字声明。
- 抽象方法只需声明而不需要实现。
- 如果一个非抽象类继承了抽象类,那么该子类必须实现抽象类中的抽象方法。
接口
接口使用interface声明
格式如下:
public interface 接口名 extends 接口1,接口2{
public static final 数据类型 常量名 = 常量值;
public abstract 返回值类型 抽象方法名称(参数列表);
}
- java使用接口的目的是为了克服单继承的限制。一个类只能有一个父类,但是一个接口可以同时继承多个父接口。接口不允许继承抽象类。
- 接口中的变量默认使用
public static final
进行修饰,即全局变量。 - 接口中定义的方法默认使用
public abstract
进行修饰,即抽象方法。 - 如果接口声明为
public
则接口中的常量和方法全部为public
。
定义接口实现类
语法格式:
修饰符 class 类名 implement 接口1,接口2,.....{
......
}
多态
- 方法的重载
- 方法的重写
对象类型的转换
- 向上转型: 子类对象—>父类对象
- 向下转型: 父类对象—>子类对象
对于向上转型,程序会自动完成。
父类类型 父类对象 = 子类实例;
对象向下转型,必须指明要转型的子类类型。
父类类型 父类对象 = 子类实例;
子类类型 子类对象 = (子类)父类对象;
在对象进行向下转型前,必须发生向上转型。
instanceof 关键字
对象 instanceof 类(接口)
如果对象是指定类的实例对象,则返回true否则 false。
Object类
Object类是所有类的父类。
内部类
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类就是内部类。
package innerclass;
public class InnerClass01 { //外部其他类
public static void main(String[] args) {
}
}
class Outer{ //外部类
private int n1 = 100; //属性
public Outer(int n1){ //构造器
this.n1 = n1;
}
public void m1(){
System.out.println("m1()");
}
{ //代码块
System.out.println("代码块。。。。。。。");
}
class Inner{ //内部类
}
}
成员内部类
成员内部类没有 static 修饰
在一个类的成员位置,编写另一个类,内部类中可以访问外部类的所有成员。
使用内部类的格式: 外部类.内部类名 对象名 = new 外部类().new 内部类();
局部内部类
局部内部类有内名
package innerclass;
public class LocalInnerClass {
public static void main(String[] args) {
Outer02 outer02 = new Outer02();
outer02.m1();
System.out.println("Outer02.this哈希地址==" + outer02);
}
}
class Outer02 { //外部类
private int n1 = 100;
private void m2() {
System.out.println("Outer 02 m2()");
}
public void m1() {
// 1、局部内部类是定义在外部类的局部位置,通常在方法中
//3、不能添加访问修饰符,但可以使用final修饰
// 4、作用域:仅仅在定义它的方法或代码块中
final class Inner02 { //局部内部类
// 2、可以访问外部类的所有成员,包含私有的
private int n1 = 800;
public void f1() {
// 5、 局部内部类可以直接访问外部类的成员
//7、如果外部类与局部内部类的成员重名时,遵循就近原则,如果访问外部类的成员,
// 则可以使用 `外部类名.this.成员` 去访问。
System.out.println("n1 = " + n1 + " 外部类的n1=" + Outer02.this.n1);
System.out.println("Outer02.this哈希地址==" + Outer02.this);
m2();
}
}
// 6、 外部类只在方法中可以创建Inner02对象,然后调用方法即可。
Inner02 inner02 = new Inner02();
inner02.f1();
}
}
- 局部内部类本质仍是一个类
- 局部内部类是定义在外部类的局部位置,通常在方法中
- 作用域:仅仅在定义它的方法或代码块中
- 如果外部类与局部内部类的成员重名时,遵循就近原则,如果访问外部类的成员,则可以使用
外部类名.this.成员
去访问。
静态内部类
静态内部类使用 static 修饰
在形式上,静态内部类只是在内部类之前增加了static关键字,但在功能上,静态内部类只能访问外部类的静态成员,通过外部类访问静态内部类成员时,可以跳过外部类直接访问静态内部类。
创建静态内部类对象
外部类名. 静态内部类名 变量名 = new 外部类名. 静态内部类名();
package com.Test;
public class Test {
public static void main(String[] args) {
Outer.Inner oi = new Outer.Inner();
oi.show();
//oi.method();
Outer.Inner.method();
}
}
class Outer{
static int num = 10;
static class Inner{
public void show(){
System.out.println("静态内部类的show方法执行了。。。。");
System.out.println("外部类的num : "+ num);
}
public static void method(){
System.out.println("静态内部类的method方法执行了。。。。。");
}
}
}
匿名内部类
匿名内部类 没有类名
创建匿名内部类
new 父类 或 父接口 {
}
异常
基本概念
Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)
执行过程中所发生的异常事件可分为两大类
- Error(错误:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError[栈溢出]和OOM(out of memory),Error是严重错误,程序会崩溃。
- Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针
对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中
断等等,Exception分为两大类:运行时异常程序运行时,发生的异常]和编
译时异常编程时,编译器检查出的异常]。
常见异常
- NullPointerException空指针异常
- ArithmeticException数学运算异常
- ArrayIndexOutOfBoundsException数组下标越界异常
- ClassCastException类型转换异常
- NumberFormatException数字格式不正确异常
try…catch 和 finally
try…catch
Java提供try和catch块来处理异常。try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。可以根据需要在程序中有多个try…catch块。
基本语法
try{
//可疑代码
//将异常生成对应的异常对象,传递给catch块
}catch(异常){
/对异常的处理
}
//如果没有finally,语法是可以通过
注意事项
如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块。
如果异常没有发生,则顺序执行try的代码块,不会进入到catch。
如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)
则使用如下代码 try…catch…finally{}
try{
//可疑代码
}catch(异常){
//
}finally{
//释放资源等.
}
try-catch-finally 执行顺序小结
1)如果没有出现异常,则执行try块中所有语句,不执行catch块中语句,如果有finally,最后还需要执行finally里面的语句.
2)如果出现异常,则try块中异常发生后,try块剩下的语句不再执行。将执行catch:块中的语句,如果有finally,最后还需要执行finally!里面的语句.
throws 关键字
- 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
- 在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
try{
//可疑代码
}catch(异常){
//
}finally{
//释放资源等.
}
try-catch-finally 执行顺序小结
1)如果没有出现异常,则执行try块中所有语句,不执行catch块中语句,如果有finally,最后还需要执行finally里面的语句.
2)如果出现异常,则try块中异常发生后,try块剩下的语句不再执行。将执行catch:块中的语句,如果有finally,最后还需要执行finally!里面的语句.
throws 关键字
- 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
- 在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。