? ? ? ? 多态就是事物的多种形态,一个对象在不同条件下所表现的不同形式。在面向对象中,接口的多种不同的实现形式就是多态。多态性就是允许将子类类型赋值给父类类型。
? ? ? ?1.有继承或实现关系:在多态中必须存在有继承或实现关系的子类和父类。
? ? ? ?2.有方法重写:子类对父类中的某些方法进行重新定义(重写,使用@Override注解进行重写)。
? ? ? ?3.有父类引用指向子类对象。
? ? ? ?父类类型??变量名?=?new?子类类型();
? ? ? ?然后通过?变量名.方法名()调用在子类中重写的方法;
? ? ? ?1.对象多态:
????????????????方法的形参定义为父类类型,这个方法就可以接收到该父类的任意子类对象了
????????Animal??a1=new??Dog();
????????Animal??a2=new??Cat();
????????2.行为多态:
????????????????同一个方法,具体多种不同表现形式或形态的能力。还可以分为:继承多态(5%),接口多态(95%)。
? ? ??
????????1.?提高程序的可扩展性:通过将接口和实现分离,使得新功能的添加和修改更加方便,降低了代码之间的紧密联系和相互依赖性。
????????2.?提高程序的可维护性:由于多态消除了类型之间的依赖关系,因此在修改某个部分时,其他部分不受影响,降低了维护难度。
????????3.?提高代码的重用性:父类或接口的方法可以被子类或实现类重写,从而实现相同功能的不同表现形式,提高了代码的利用率。
????????1.成员变量:编译看左边(父类),运行看左边(父类)。
????????2.成员方法:编译看左边(父类),运行看右边(子类)。
访问成员方法时,在编译的时候,首先会检查父类中有没有这个方法,没有:编译出错。有:编译通过,但是运行的时候,一定会执行子类的方法逻辑。
????????1.多态情况下,子类和父类存在同名的成员变量时,访问的时父类的成员变量。
????????2.多态情况下,子父类存在同名的非静态成员方法时,访问的是子类中重写的方法。
????????3.多态情况下,子父类存在同名的静态成员变量成员方法时,访问的是父类的成员函数。
????????4.多态情况下,不能访问子类独有的方法。
????????从子到父(父类引用指向子类对象)
?????????Fu??f=new??Zi();
????????优点:可以直接转换。
????????缺点:不能调用子类中特有的方法。
????????从父到子(将父类引用所指向的对象,转交给子类类型),需要强转。
????????Zi??z=(Zi)?f;
????????优点:转换后父类可以使用子类中特有的方法。
????????缺点:当[实际类型]和[目标类型]不匹配,会出现类型转换异常(ClassCastException)。
解决方式:利用instanceof?判断左边的引用,是否是右边的数据类型。
????????抽象类:如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类一般使用abstract关键字来定义。
抽象类是一种特殊的类,与类的区别只是抽象类不能被实例化,既然不能被实例化(Person?p?=?new?Person();),所以抽象类必须被继承,才能被使用。
????????定义格式:
????????public??abstract??class??类名{?};
????????抽象方法:将共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义为抽象方法。
????????定义格式:
????????????????public??abstract??返回值类型??方法名(参数列表);
????????1.?抽象类不能实例化:如果抽象类允许创建对象,就可以调用内部没有方法体的抽象方法了,这样做没有意义。
????????2.抽象类存在构造方法:交给子类,通过super进行访问,但是不能new。
????????3.抽象类中可以存在普通方法:可以让子类继承到,继续使用。
????????4.抽象类的子类:要么重写抽象类中的所有抽象方法,要么是抽象类
????????5.?含有抽象方法的类一定是抽象类。
????????6.抽象类中可以有具体的属性。
???????
接口就是一种规范的标准,只要符合这个标准都可以通用,接口的表现在于对行为的抽象。
如果发现一个类,所有的组成都是抽象方法,没有成员变量,没有普通方法,这种类,通常会设计为Java中的接口,因为现在这个类存在的唯一价值,就只是声明规则
接口其实就是一个特殊的抽象类,可以多继承。
[权限修饰符]??interface??接口名{?}
1.私有权限(private)
private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用。
2.默认权限(default)
类,数据成员,构造方法,方法成员,都能够使用默认权限,即不写任何关键字。默认权限即同包权限,同包权限的元素只能在定义它们的类中,以及同包的类中被调用。
3.受保护权限(protected)
protected可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。被protected修饰的成员,能在定义它们的类中,同包的类中被调用。如果有不同包的类想调用它们,那么这个类必须是定义它们的类的子类。
4.公共权限(public)
public可以修饰类,数据成员,构造方法,方法成员。被public修饰的成员,可以在任何一个类中被调用,不管同包或不同包,是权限最大的一个修饰符。
概括:
允许所有外部类访问使用public
允许子类和同包类访问使用protected
只能自己访问使用private
访问权限修饰符权限从高到低排列是public?>protected?>default>?private
访问修饰符 | 同一个类 | 同一个包 | 不同包,子类 | 不同包,非子类 |
private | √ | × | × | × |
default | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
有关Java语言的修饰符,需要注意的问题有如下几个:
1.并不是每个修饰符都可以修饰类(指外部类),只有public和default可以。
2.所有修饰符都可以修饰数据成员,方法成员,构造方法。
3.为了代码安全起见,修饰符不要尽量使用权限大的,而是适用即可。比如,数据成员,如果没有特殊需要,尽可能用private。
4.修饰符修饰的是“被访问”的权限。
?
????????接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为?public?abstract(只能是?public?abstract,其他修饰符都会报错)。
????????接口中可以含有变量,但是接口中的变量会被隐式的指定为?public?static?final?变量(并且只能是?public,用?private?修饰会报编译错误)。
????????接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
1.一个接口可以有多个方法。
2.接口文件保存在?.java?结尾的文件中,文件名使用接口名。
3.接口的字节码文件保存在?.class?结尾的文件中。
4.接口相应的字节码文件必须在与包名称相匹配的目录结构中。
1.接口不能用于实例化对象。
2.接口没有构造方法。
3.接口中所有的方法必须是抽象方法,Java?8?之后?接口中可以使用?default?关键字修饰的非抽象方法。
4.接口不能包含成员变量,除了?static?和?final?变量。
5.接口不是被类继承了,而是要被类实现。
6.接口支持多继承。
1.抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
2.?抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是?public?static?final?类型的。
3.?接口中不能含有静态代码块以及静态方法(用?static?修饰的方法),而抽象类是可以有静态代码块和静态方法。
4.?一个类只能继承一个抽象类,而一个类却可以实现多个接口。
5.抽象类不能被实例化,而接口可以。