文章目录
- 继承
- 一、继承的特点
- 二、强制类型转换
- 三、参数传递
- 接口
- 一、接口的特点
- 二、接口的用法
- 三、接口与抽象类的区别
- 多态
- 一、重载和覆盖(重写)
- 二、多态的定义格式
- 三、多态成员变量和成员方法的特点
继承
一、继承的特点
(1)java的单继承性:
java规定一个类只能继承一个父类(因为多继承有安全问题,比如多个父类可能有同名方法或者成员变量,子类不知道调用哪个父类的方法或成员变量)
但是java可以实现多层继承(接口的多继承)
(2)子类与父类的修饰:
子类的访问控制符权限只能大于或等于父类(当父类的方法是public时,子类覆盖的方法一定要声明为public)
(3)阻止继承:
如果不希望再产生子类,可以在类的声明之前加上final,这样此类就不能再被继承。例如public fianl class abc,final类中的所有方法自动的成为fianl方法。不包括域(成员变量)
(4)创建对象过程:
在创建子类对象时,会先调用父类的构造器,初始化继承自父类的成员。然后,调用子类的构造器,初始化子类的成员。
二、强制类型转换
定义: 将某个类的对象引用转换成另外一个类的对象引用。
举例: Manager boss = (Manager) staff[0];
注: (1)将一个值存入变量时,编译器将检查是否允许该操作。将一个子类的引用赋给一个父类变量,编译器是允许的,但将一个父类的引用赋给一个子类变量,必须进行类型转换。
(2)在将父类转换成子类之前,应该用儿子 instanceof(爸爸)进行检查。否则容易产生ClassCastException异常,程序就会终止。
(3)只能在具有继承关系的才能进行类型转换。
三、参数传递
通过图中的两段程序可以得出如下结论:
(1)当调用方法时,如果传入的数值为基本数据类型(包含String类型),形式参数的改变对实际参数无影响
(2)当调用方法时,如果传入的数值为引用数据类型(String类型除外),形式参数的改变对实际参数有影响
接口
一、接口的特点
- 接口最重要的体现:解决多继承的弊端。将多继承这种机制在java中通过多实现完成了。
- 接口中所有的方法自动的属于public,因此,在接口中声明方法时,不必提供关键字public。但在实现接口时,必须把方法声明为public。(接口中的方法均为公共访问的抽象方法,接口中无法定义普通的成员变量)
- 接口不是一个类,所以不能用关键字new来生成一个接口的实例,但是可以声明一个接口变量。若要生成一个接口的实例,可以让接口变量指向一个已经实例化此接口的类的对象。
- 子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化,否则子类是一个抽象类。(即实现类实现接口时,重写接口全部的抽象方法,创建实现类对象.(若实现类只重写了一部分抽象方法,那么实现类还是一个抽象类))
二、接口的用法
• 普通用法
class pepole implements eat{
}• 接口也可以继承
interface student extends school{
}• 类可以同时实现多个接口
class Zi implements Fu1,Fu2{
}• 类可以同时实现继承和接口
class Zi extends Fu implements Inter {
}• 接口的多继承(java中类没有多继承,接口之间有多继承)
interface Fu1{
void show();
}
interface Fu2{
void show1();
}
interface Fu3{
void show2();
}
interface Zi extends Fu1,Fu2,Fu3{
void show3();
}
三、接口与抽象类的区别
(1)二者的异同
相同点 | 不同点 |
都位于继承的顶端,用于被其他类实现或继承 | 抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性;接口只能包含抽象方法 |
都不能直接实例化对象 | 一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承) |
都包含抽象方法,其子类都必须覆写这些抽象方法 | 抽象类是这个事物中应该具备的内容, 继承体系是一种 is…a关系 |
\ | 接口是这个事物中的额外内容,继承体系是一种 like…a关系 |
(2)二者的选用
- 优先选用接口,尽量少用抽象类
- 需要定义子类的行为,又要为子类提供共性功能时才选用抽象类
多态
多态有两种表现形式(重载和覆盖(重写)),多态的前提必须是有子父类关系或者类实现接口关系没否则无法完成多态。
一、重载和覆盖(重写)
重载: 是在同一个类中的重载,方法名一样,参数列表不同,同一个类的事情。
重载的注意事项:
1.重载方法参数必须不同:
- 参数个数不同,如method(int x)与method(int x,int y)不同
- 参数类型不同,如method(int x)与method(double x)不同g
- 参数顺序不同,如method(int x,double y)与method(double x,int y)不同
2.重载只与方法名与参数类型相关与返回值无关
如void method(int x)与int method(int y)不是方法重载,不能同时存在
3.重载与具体的变量标识符无关
如method(int x)与method(int y)不是方法重载,不能同时存在
重写: 是在继承关系中,子类中,出现了和父类一模一样的方法的时候,子类重写父类的方法,覆盖.(要保证子类方法的权限大于或等于父类方法的权限)。
用多态的父类引用变量来调用方法时,会调用子类重写后的方法,如下代码所示:
public class Demo {
public static void main(String[] args){
father f = new son();
f.print1();
}
}
class father{
public void print(){
System.out.println("这是父类的print函数");
}
}class son extends father{
public void print(){
System.out.println("这是儿子的print函数");
}
public void print1(){
System.out.println("这是儿子的print1函数");
}
}
运行结果: 没有通过编译,因为f是父类的数据类型,那么在父类中没有print1方法,只有print方法。又由于这个是指向子类对象,所以其只能操作子类重写父类的方法。若改为f.print();则编译通过,输出子类的print方法。
二、多态的定义格式
- 普通类多态的定义格式
父类类型 变量名 = new 子类类型();
变量名.方法名();
eg: class Fu {
}
class Zi extends Fu {
}
Fu f = new Zi(); //类的多态使用
- 抽象类多态的定义格式
abstract class Fu {
public abstract void method();
}
class Zi extends Fu {
public void method(){
System.out.println(“重写父类抽象方法”);
}
}
Fu fu= new Zi(); //类的多态使用
- 接口多态的定义格式(与抽象类类似)
interface Fu {
public abstract void method();
}
class Zi implements Fu {
public void method(){
System.out.println(“重写接口抽象方法”);
}
}
Fu fu = new Zi(); //接口的多态使用
三、多态成员变量和成员方法的特点
(1)成员变量
编译和运行都参考等号的左边。编译运行看左边。
(2)成员方法
编译看左边,运行看右边。
class Fu {
int num = 4;
void show() {
System.out.println("Fu show num");
}
}
class Zi extends Fu {
int num = 5;
void show() {
System.out.println("Zi show num");
}
}
class Demo {
public static void main(String[] args) {
Fu f = new Zi(); 左边 = 右边
System.out.println(f.num);
f.show();
}
}
运行结果