java的三大特性:封装、继承、多态
4.1 类的继承
4.1.1 继承的概念
在程序中,继承描述的是事物之间的所属关系。
(例如:猫和狗都属于动物系、小学生和中学生都属于学生系)
继承的好处:提高代码的重用性
(在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作“子类”,现有类别成为“父类”。)
(子类继承父类的属性和方法,使得子类对象(实例)具有父类的特征和行为。)
(子类除了继承父类的属性和方法,子类也可以定义自己的属性和方法)
继承的语法:
class 子类 extends 父类 {
………………
}
继承的注意事项:
1.单继承(一个类只能有一个直接父类)
2.多个类可以继承同一个父类(一个父类可以有多个子类)
3.多层继承(子类可以有它的子类,父类也可以有它的父类)
4.子类不能访问父类的私有成员
4.1.2 方法重写
注:
区分 方法重写 与 方法重载
方法重写 特点:
1.要有继承(不在同一个类中)(子类重写父类的方法)
2.方法名、参数、返回值类型都要相同
3.子类重写的方法,不能拥有比父类更严格的访问权限(Public > Protected > Default > Private)
方法重载 特点:
1.在同一个类中
2.方法名相同
3.参数列表不同(个数、类型)
4.跟访问权限和返回值类型无关
4.1.3 super关键字
用法
1.访问父类的成员变量––––super.成员变量
2.访问父类的成员方法––––super.成员方法()
3.访问父类的构造方法––––super(参数…)
与this的区别
注:this与super在调用构造方法时,都要求必须放在构造方法的首行。因此,两者不能同时出现。
区别点 | this | super |
属性访问 | 访问本类中的属性,如果本类中没有该属性,则从父类中查找。 | 访问父类中的属性 |
方法 | 访问本类中的方法,如果本类中没有该方法,则从父类中继续查找 | 直接访问父类中的方法 |
调用构造 | 调用本类构造,必须放在构造方法的首行 | 调用父类构造,必须放在子类构造方法的首行 |
4.2 final 关键字
final的英文意思是“最终”
在Java中,可以使用final关键字声明类、方法、属性,在声明时需要注意以下几点:
- 使用final修饰的类不能有子类
- 使用final修饰的方法不能被子类重写
- 使用final修饰的变量是常量(成员变量、局部产量),常量不可以被修改
示例第一种情况
示例第二种情况
示例第三种情况
4.3 抽象类
当定义一个类时,常常定义一些成员方法来描述类的行为特征,但有时这些方法的实现方式是无法确定的。(例如:上面在定义Animal类时,bark()方法用于描述动物的叫声,但针对不同动物,叫声是不同的,因为bark()方法无法准确描述动物的叫声)
因此,我们需要用到 抽象方法
抽象方法是使用abstract关键字修饰的成员方法,抽象方法在定义时不需要实现方法体。抽象方法的定义格式为: abstract void 方法名称(参数);
/注:
当一个类包含了抽象方法,该类必须是抽象类。
抽象类中不一定有抽象方法。
抽象类和抽象方法一样,必须使用abstract关键字进行修饰。
抽象类的定义格式如下:
abstract class 抽象类名称{
访问权限 返回值类型 方法名称(参数){
return [返回值];
}
访问权限 abstract 返回值类型 抽象方法名称(参数); //抽象方法,无方法体
}
抽象类的定义规则:
(1)包含一个以上抽象方法的类必须是抽象类。
(2)抽象类和抽象方法都要使用abstract关键字声明。
(3)抽象方法只需声明而不需要实现。
(4)如果一个类继承了抽象类,那么该子类必须实现抽象类中的全部抽象方法。
///使用abstract关键字修饰的抽象方法不能使用private修饰,因为抽象方法必须被子类实现,如果使用了private声明,则子类无法实现该方法。
4.3.2 接口
如果一个抽象类的所有方法都是抽象的,则可以将这个类定义接口。
接口是一种特殊的类,由全局常量和公共的抽象方法组成,不能包含普通方法。
接口使用interface关键字声明,语法格式如下:
public interface 接口名 extends 接口1,接口2... {
public static final 数据类型 常量名 = 常量值;
public default 返回值类型 抽象方法名(参数列表);
public abstract 返回值类型 方法名(参数列表){
//默认方法的方法体
}
public abstract 返回值类型方法名(参数列表){
//类方法的方法体
}
}
///“extends 接口1,接口2...”表示一个接口可以有多个父接口,父接口之间使用逗号分隔。Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个接口可以同时继承多个父接口。
接口中的变量默认使用“public static final”进行修饰,即全局常量。
接口中定义的方法默认使用“public abstract”进行修饰,即抽象方法。
如果接口声明为public,则接口中的变量和方法全部为public。
在接口中定义常量时,可以省略前面的“public static final”,此时,接口会默认为常量添加“public static final”。
与抽象类一样,接口的使用必须通过子类,子类通过implements关键字实现接口,并且子类必须实现接口中的所有抽象方法。
一个类可以同时实现多个接口,多个接口之间需要使用英文逗号(,)分隔。
定义接口的实现类,语法格式如下:
修饰符 class 类名 implements 接口1,接口2,...{
...
}
例如:
如果在开发中一个子类既要实现接口又要继承抽象类,则可以按照以下格式定义子类:
修饰符class 类名 extends 父类名implements 接口1,接口2,... {
...
}
在Java中,接口是不允许继承抽象类的,但是允许一个接口继承多个接口。
例如:
/
第11~13行代码定义了接口Action并继承接口Animal和Color,这样接口Action中就同时拥有Animal和Color接口中info()和black()方法以及本类中shout()方法
在第15~28行代码定义了一个Dog类并实现了Action接口,这样Dog类就必须同时实现这3个抽象方法。
4.4
4.4.1 多态
Java中多态主要有以下两种形式:
- 方法的重载
- 对象的多态性(方法重写)
例如:
对象类型转换主要分为以下两种情况:
- 向上转型:子类对象→父类对象
- 向下转型:父类对象→子类对象
(对于向上转型,程序会自动完成,而向下转型时,必须指明要转型的子类类型)对象类型的转换格式如下所示:
对象向上转型:父类类型 父类对象 = 子类实例;
对象向下转型: 父类类型 父类对象 = 子类实例;
子类类型 子类对象 = (子类)父类对象;
///向上转型:
/第20~22行代码是创建了一个dog对象,并将dog对象向上转型成Animal类型的对象an,然后使用对象an调用shout()方法。
从程序的运行结果中可以发现,虽然是使用父类对象an调用了shout()方法,但实际上调用的是被子类重写过的shout()方法。
也就是说,如果对象发生了向上转型关系后,所调用的方法一定是被子类重写过的方法。
父类Animal的对象an是无法调用Dog类中的eat()方法的,因为eat()方法只在子类中定义,而没有在父类中定义。
向下转型:
第22行代码发生了向上转型,将Dog类的实例转换成了Animal类的实例an,第21行代码是将Animal类的实例转换为Dog类的实例。
第24行代码使用dog对象调用shout()方法,由于Animal类的shout()方法已被子类Dog类重写,因此dog对象调用的方法是被子类重写过的方法。
在向下转型时,不能直接将父类实例强制转换为子类实例,否则程序会报错。
例如,上述代码 Dog dog = (Dog)new Animal(); //则会编译错误
4.4.3 instanceof关键字
Java中可以使用instanceof关键字判断一个对象是否是某个类(或接口)的实例
语法格式如下:
对象 instanceof类(或接口)
在上述格式中,如果对象是指定的类的实例对象,则返回true,否则返回false。
例如:
///
第22行代码实例化Dog类对象,并将Dog类实例向上转型为Animal类对象a1
第23行代码是通过instanceof关键字判断对象a1是否是Animal类的实例
第24行代码是通过instanceof关键字判断对象a1是否是Dog类的实例
第25行代码是实例化了一个Animal类对象a2
第26行代码是通过instanceof关键字判断对象a2是否是Animal类的实例
第27行代码通过instanceof关键字判断对象a2是否是Dog类的实例
4.5 Object类
Object类,它是所有类的父类,每个类都直接或间接继承Object类,因此Object类通常被称之为超类。
当定义一个类时,如果没有使用extends关键字为这个类显式地指定父类,那么该类会默认继承Object类。
Object类常用方法如下表:
方法名称 | 方法说明 |
boolean equals() | 判断两个对象是否“相等” |
int hashCode() | 返回对象的哈希码值 |
String toString() | 返回对象的字符串表示形式 |
示例Object类中toString()方法的使用:
但在实际开发中,通常希望对象的toString()方法返回的不仅仅是基本信息,而是对象特有的信息,这时可以重写Object类的toString()方法。
到这先暂停啦..