多态,抽象类,接口
来源:互联网 发布:程序员大牛 编辑:程序博客网 时间:2024/05/29 04:33
一.多态
1.概念:一个事物在不同时刻体现出的不同状态.
2.三个前提条件:
a.必须有继承关系,没有继承关系,谈不上多态;
b.必须有方法重写;
子类出现了父类一样的方法声明.
c.有父类引用指向子类对象:向上转型
Fuf = new Zi();
多态的三个条件缺一不可;
3.多态的成员访问特点:
a.成员变量:编译看左,运行看左;
b.成员方法(非静态的成员方法):
编译看左,运行看右,由于存在方法重写,所以最终运行的是子类的成员方法.
c.静态成员方法(静态方法算不上方法重写,静态直接跟类有关系!)
编译看左,运行看左;
d.构造方法: 对对象进行初始化,由于是继承关系,所以还是分层初始化.
//父类
class Fu{
publicintnum=10;
//父类的成员方法
publicvoid show() {
System.out.println("show Fu..");
}
//静态方法
publicstaticvoid function() {
System.out.println("function Fu...");
}
}
//子类
class Ziextends Fu{
intnum = 20;
publicvoid show() {
System.out.println("show Zi");
}
publicstaticvoid function() {
System.out.println("function Zi");
}
}
//测试类
publicclass DuoTaiTest {
publicstaticvoid main(String[]args) {
//创建父类的对象:多态的形式
//有父类引用指向子类对象:向上转型
Fu f = new Zi();
//访问成员变量
System.out.println(f.num);
//调用成员方法:show()
f.show();
//静态方法
f.function();
}
}
4.多态的好处(特点):
a.提高代码的维护性(由继承保证)
b.提高代码的扩展性(由多态保证)
java开发原则:高内聚,低耦合.
5.多态的弊端:
不能访问子类特有的方法
解决方案:
a.创建子类的具体对象,来访问自己的特有功能;虽然可以解决多态的弊端,但是从内存角度考虑,需要创建子类对象,那么必须在堆内存开辟空间,耗费内存,浪费空间!
b.既然多态的第三个前提条件:父类引用指向子类对象,那么可不可以将子类的引用指向父类对象呢?
可以的:向下转型:将父类的引用强制转换为子类的引用:前提必须有父类的引用存在;
向下转型必须依赖于向上转型! Zi z = (Zi) f;
class孔子爹{
publicintage=40;
publicvoid teach() {
System.out.println("讲解JavaSE..");
}
}
class孔子extends孔子爹{
publicintage = 20;
publicvoid teach() {
System.out.println("讲解论语...");
}
//特有功能
publicvoid playGame() {
System.out.println("王者荣耀...");
}
}
publicclass孔子装爹 {
publicstaticvoid main(String[]args) {
孔子爹k爹 =new孔子();//向上转型:父类引用指向子类对象
System.out.println(k爹.age);//成员变量:编译看左,运行看左
k爹.teach();// 非静态成员方法:编译看左,运行看右
孔子k = (孔子)k爹;//向下转型
k.playGame();//访问子类的特有功能
}
}
5.一般情况下:向下转型使用不当会造成一个异常:
Throwable:
error:严重问题
Exception:
编译时期异常:
运行时期异常:RuntimeException
运行时期异常:
类转换异常: ClassCastException
ArrayIndexOutBoundException:数组角标越界异常;
NullPointerException:空指针异常(解决方案:给对象做非空判断)
If(对象名=null){
给该对象进行操作;
}
测试:看程序写结果
//看程序写结果
class A{
publicvoid show() {
show2();
}
publicvoid show2() {
System.out.println("我");
}
}
class Bextends A{
publicvoid show2() {
System.out.println("爱");
}
}
class Cextends B {
publicvoid show() {
super.show();
}
publicvoid show2() {
System.out.println("你");
}
}
publicclass DuoTaiTest2 {
publicstaticvoid main(String[]args) {
A a = new B();
a.show();
B b = new C();
b.show();
}
}
有继承关系:
分层初始化:父类先初始化,然后子类初始化
多态的访问特点:
成员方法:(非静态的):编译看左,运行看右(方法重写)
二.抽象类
1.概念:
每一个动物的吃和睡的功能不一样,不应该把动物类定义为一个具体类,而是给出一个声明(abstract)
当一个类中如果有抽象功能(抽象方法)的时候,那么这个类一定要定义为抽象类!
abstract class 类名{}
问题:一个抽象类中可以有非抽象方法吗?
一个抽象类中可以抽象,也可以有非抽象的(作为一个判断题记忆!)
抽象类不能实例化:抽象类不能创建对象
一个抽象类如何进行实例化:
通过抽象类多态形式:父类的引用指向子类对象,通过子类进行初始化!
抽象类的子类的特点:
1)抽象类的子类是抽象类,那么没有意义!
最终使用的就是通过子类进行对象初始化的,如果子类都被抽象修饰了,那么也不能创建对象,所以没意义
抽象类多态:
强制子类必须重写当前抽象的父类中所有的抽象方法
还可以提高代码的维护性(继承关系保证!)
Eg:
abstractclass Animal{
//抽象方法:没有方法体的一个方法
publicabstractvoid eat();
publicabstractvoid sleep();
//具体方法
publicvoid show() {
System.out.println("show Animal..");
}
}
class Catextends Animal{
@Override
publicvoid eat() {
System.out.println("猫吃鱼..");
}
@Override
publicvoid sleep() {
System.out.println("猫趴着睡觉..");
}
}
//测试类
public class AbstractTest1 {
publicstaticvoid main(String[]args) {
Animal a = new Cat();//多态:父类引用指向子类对象
a.show();
a.eat();
a.sleep();
}
}
抽象类的成员特点
成员变量:
可以是变量也可以是自定义常量
构造方法:
抽象类可以有构造方法:包括有参构造和无参构造
作用:通过抽象类多态的形式:让子类进行数据的初始化
成员方法:
可以有抽象方法,也可以有非抽象方法
抽象类的成员方法特性:
抽象方法:强制子类必须要做到一件事情:方法重写(覆盖)
非抽象方法:由继承保证可以去提高代码的复用性
abstractclass Fu2{
private Stringname;
privateintage;
//成员变量
publicintnum=100;
publicfinalintnum2=200;//被final修饰,自定义常量
//无参构造
public Fu2() {
}
//有参构造
public Fu2(Stringname,intage) {
this.name=name;
this.age=age;
}
//抽象方法
publicabstractvoid show();
//非抽象方法
publicvoid function() {
System.out.println("function Fu2");
}
}
//子类
class Zi2extends Fu2{
publicvoid show() {
System.out.println("show Zi2");
}
}
//测试类
publicclass AbstractTest2{
publicstaticvoid main(String[]args) {
Fu2 f = new Zi2();
f.show();
f.function();
System.out.println(f.num2);
}
}
问题:
一个类中如果没有抽象方法,那么这个类可不可以定义为一个抽象类呢?
可以!为什么
不能让其创建对象!
abstract不能和哪些关键字共同使用?
private和abstract不能共同使用
final和abstract不能共同使用
static和abstract不能共同使用
实际开发中:public公共访问权限
三.接口
接口的概念:
接口体现的是一种:扩展功能: 比如:猫可以跳高(并不是所有的猫都具有跳高功能)
如何表示接口:
interface:接口 interface 接口名{
}
接口里面的方法可以是非抽象方法吗?
不可以,只能是抽象方法
接口中不能有构造方法
接口的特点:不能实例化(不能直接创建对象)
接口如何实例化:
接口的子实现类:
1)接口的子实现类是抽象类,没有意义,子类都不能创建对象了;实际开发中用的就是子类的对象进行初始化!
2)接口的子实现类是非抽象类
接口的实例化:就是通过子实现类对数据进行初始化!
接口的子实现类和接口的关系:implements:
格式:
class子实现类名 implments(实现) 接口名{
}
//定义跳高的接口
publicinterface Jump {
//抽象方法
publicabstractvoid jump();
//接口中不能有非抽象方法和构造方法.
}
//子实现类
classCat2implements Jump{
publicvoid jump() {
System.out.println("猫可以调高了");
}
}
//测试类
publicclass InterfaceTest1 {
publicstaticvoid main(String[]args) {
//接口对象:接口的引用指向子类对象
Jump j = newCat2();
j.jump();
}
}
接口成员的特点:
成员变量:
只能是常量:存下默认修饰符:publicstatic final (永远建议自己给出默认修饰符)
构造方法:
接口是没有构造方法的
成员方法:
接口中的成员方法默认修饰符:publicabstract(永远建议自己给出默认修饰符)
//定义一个接口
publicinterface Inter {
//成员变量:只能是常量,存在默认修饰符public static final
publicstaticfinalintnum1=10;
publicstaticfinalintnum2=20;
//成员方法:默认修饰符:public abstract
publicabstractvoid show();
publicabstractvoid function();
}
//定义接口的子实现类
publicclass InterImp1implements Inter {
@Override
publicvoid show() {
System.out.println(num1);
System.out.println(num2);
}
@Override
publicvoid function() {
System.out.println("function InterImp1..");
}
}
//测试类
publicclass InterfaceTest2 {
publicstaticvoid main(String[]args) {
Inter i = new InterImp1();
System.out.println(Inter.num1);//接口名.成员变量(当前变量被static修饰)
System.out.println(Inter.num2);
System.out.println("--------------------");
i.show();
i.function();
}
}
类与类的关系:
继承关系:extends,java中只支持单继承,不支持多继承,但是可以多层继承!
类与接口的关系
实现关系:implements,并且,一个类在继承另一个类的同时,可以实现多个接口
(class 子实现类名 enxtends Object implements 接口名1,接口名2...)
接口与接口的关系
继承关系:extends,可以支持单继承,也可以多继承!
interface Inter2{
}
interface Inter3{
}
//接口与接口的关系:extends
interface Zi extends Inter2{}
interface Son extends Inter2,Inter3{}
//子实现类
class InterImpl2 extends Object implements Inter2,Inter3{
}
public class InterfaceDemo3 {
}
面试题:
接口和抽象类的区别?
1)成员的区别:
成员变量:
抽象类:成员变量可以是常量,也可以是变量
接口:成员变量只能是一常量:存在默认修饰符:publicstatic final
构造方法:
抽象类:可以有无参构造,有参构造方法
作用:通过子类进行数据初始化(通过子类创建对象)
接口:没有构造方法的
成员方法的区别:
抽象类:可以有抽象方法,也可以有非抽象方法
接口:只能是抽象方法:存在默认修饰符:publicabstract
2)关系的区别:
类与类的关系:
继承关系:extends,java中只支持单继承,不支持多继承,但是可以多层继承!
类与接口的关系:
实现关系:implements,并且,一个类在继承另一个类的同时,可以实现多个接口
(class子实现类名 enxtends Object implements 接口名1,接口名2...)
接口与接口的关系
继承关系:extends,可以支持单继承,也可以多继承!
3)设计理念的区别:
抽象类:
体现的是一种"isa"的关系,存在继承关系!(抽象类多态)
接口:
体现的是一种"likea"的关系,由于接口的一种扩展功能
- 多态,抽象类,接口
- 抽象类、接口、多态
- 多态、抽象类、接口
- 抽象类 接口 多态
- 多态、抽象类、接口
- 多态,抽象类,接口
- 抽象类 接口 多态
- 多态,抽象类,接口
- 抽象类 接口 多态
- 多态 抽象类 接口
- 多态,抽象类,接口
- 多态-抽象类-接口
- 多态/接口/抽象类
- 继承、多态、抽象类、接口
- 接口,抽象类,继承,多态
- 5 多态 抽象类 接口
- 继承,抽象类,接口,多态
- 继承、多态、接口、抽象类
- 针对一些自定义的,中央仓库没有的jar包,需要从将jar放到lib中
- 1.Python---01
- vue computed 与 watch 区别
- JSP中的<%= %>和${ }到底有什么区别?
- CSS Mastery摘要(5)--Content Layout
- 多态,抽象类,接口
- [python3]爬虫实战二之爬取百度贴吧帖子
- xUtils-2.6.14在android5.0以下系统https问题
- Python画地图数据可视化分析
- ofbiz总结——常用XML结构定义文档链接
- 实用shell脚本 安装集群使用
- 虚拟机下在终端调节屏幕分辨率(ubuntu)
- BP神经网络
- jQuery.extend 函数使用详解