[封装继承多态]java-day09

继承  -面向对象的第二大特性

http://t.csdn.cn/uKZxZ

紧接前文

没有继承关系之前

指针可以指向对象,前提条件是:

指针的数据类型与对象数据类型必须一样

有了继承关系之后

指针的数据类型与对象数据类型不一样

如果存在继承关系,那么父类的类型指针可以指向子类类型的对象

Object类型的指针可以指向任意类型的对象

这种将子类对象赋给父类指针的语法称为“向上转型”,也是隐式的

继承是向上转型的前提

向上转型是多态的前提

向上转型有副作用:指针无法访问下级对象的成员

“向下转型”需要显示的强制转换,通常伴随着instanceof做类型判断

指针向下转型为下级类型,就可以访问下级对象中的成员了

如果使用了向上转型实现了多态指针,再用指针操作对象的时候又不想做“向下转型”可以使用方法重写来实现

思考:Animal类型的指针为什么不能调用show()方法

因为Animal中没有show()方法

1.在父类Animal中添加一个show()方法

animalArray[i].show();此时animalArray[i]不需要向下转型也可以调用show()方法

2.当子类中出现与父类中的同名方法的时候,就存在一种方法重写的关系

那么此时当使用父类类型指针调用方法的时候,如果当前子类中存在有满足重写关系的方法的时候,会自动去向下调用子类重写的方法

abstract关键字:抽象

可以修饰成员方法和类

成员方法被abstract修饰后,称为抽象方法/虚方法,没有()方法体

类被abstract修饰后,称为抽象类,不可以被实例化

当一个类中出现了抽象方法时,这个类必须变为抽象类

抽象方法必须出现在抽象类中,而抽象类中不一定必须有抽象方法

例如:animal类被abstract修饰,成为抽象类

Animal animal = new Animal();//报错,抽象类不可用被实例化

抽象类天生就是父类,天生就是被子类继承的

子类继承抽象类的时候,必须强制重写父类的抽象方法

子类继承父类的时候,如果父类中有抽象方法,子类必须要重写,除非把子类也变为抽象类,让子类的子类去重写(实现)

例如:Dog,Cat,Pig这三个子类继承Animal父类

Dog dog = new Dog();//一定正确

Cat cat = new Cat();//一定正确

Pig pig = new Pig();//一定正确

Animal animal1 = new Dog();//如果有继承关系Dog extends Animal就正确

Animal animal2 = new Cat();//如果有继承关系Cat extends Animal就正确

Animal animal3 = new Pig();//如果有继承关系Pig extends Animal就正确

Object object1 = new Dog();//一定正确

Object object2 = new Cat();//一定正确

Object object3 = new Pig();//一定正确

Dog dog = new Cat();//不正确

Cat cat = new Pig();// 不正确

越向上转型,不能访问的对象越多

越向上转型,指针的数据类型越抽象

Dog dog = new Dog();

Animal animal1 = new Dog;

Object object1 = new Dog();

多态-面向对象的第三大特性

与多态相反的是单太

多态的指针(指针的类型的 抽象的)

Animal animal

单太的指针(指针的类型是具体的)

Dog dog

Cat cat

Pig pig

多态 的数组,数组元素是指针,也是指针多态

单态 的数组,数组元素是指针,也是指针单态

面向对象的整理

面向过程和面向对象的区别

面向过程编程思想不考虑封装,继承,多态这些事情,直接定义数据为静态变量,用静态函数操作数据,基于过程编程,面向过程编程,代码不具有可复用性和可扩展性

面向对象的编程思想需要先抽象出实体的结构,并用类进行封装,用成员变量表达实体的属性,用成员方法封装对实体属性的操作,通过构造方法构造对象,基于对象编程,面向对象编程,代码具有可复用性和可扩展性

举例:实现汽车租赁系统

面向过程的思想:

定义多个静态数组,存储汽车各项数据,直接定义静态函数实现各种业务过程

面向对象的思想:

先抽象出汽车实体的结构,并使用汽车类进行封装,然后创建汽车数组存储汽车实体的数据,再考虑业务功能的实现

面向对象的三大特征

1.封装

第一特性:封装

用成员变量来描述对象的属性,并用private进行私有化封装,不对外暴露对象的属性,防止外部对属性误操作

用成员方法来封装对属性的操作,并暴露给外部调用,典型的就是setter和getter,一个是通过给外部进行属性设置,一个是通过给外部读取属性的值

2.继承

第二特性:继承

1.继承是java中类与类之间的一种关系

2.继承的关键字是extends

3.发生继承的类称为子类,被继承的类称为父类

4.java不支持多继承,只支持单继承,但支持多级继承,一个类只能继承父类,但是一个父类可以有多个子类

5.如果一个类没有显示的继承父类,则 隐 式继承Object类

6.子类可以继承父类的非私有(非private修饰)成员

7.父类的构造方法子类不能继承,但可以使用super()调用

8.父类的静态成员与继承无关

9.如果父类中有抽象方法,子类必须要重写,除非把子类也变为抽象类,让子类的子类去重写(实现)

3.多态

第三特性:多态

先有继承而后有多态,多态的反义词是多态

1.指针的多态(数组的多态,参数的多态,返回值的多态归根到底都是指针的多态

如果指针是具体的子类类型,则指针是单太指针,只能指向具体的子类对象

如果指针是抽象的父类类型,则指针是多太指针,只能指向任意的子类对象

2.方法的多态(1.基于重载实现 2.基于重写实现

重载是编译时多态的体现

重写是运行时多态的体现

重载和重写的区别

重载和重写都是方法多态的体现

重载overload是编译时多态的体现

1.重载发生在同一个类中,java允许多个方法同名,但必须满足重载的要求

2.方法名相同,但是方法的参数列表不同(可以是参数的个数不同,或者是参数类型不同)

3.静态方法,构造方法,成员方法都可以重载

重写override是运行时多态的体现

1.重写是发生在子类与父类之间 ,子类重写父类的方法,其目的是为了,当使用父类型的指针调用子类方法的时候,可以无需做向下转型。

2.子类方法与父类方法同名

3.访问修饰符要大于等于父类方法

4.参数的个数必须与父类一样,参数类型可以小于父类方法的参数类型

5.返回值类型可以小于等于父类方法的返回值类型

抽象类和抽象方法的关系

1.抽象类和抽象方法都需要使用abstract关键字修饰

2.抽象方法必须出现在抽象类中

3.抽象类中可以有抽象方法,也可以没有

普通类和抽象类的区别

普通类可以实例化,也可以被继承

抽象类不可以实例化,只能被继承

实例化就是new构造方法()创建对象

向上转型和向下转型的区别

向上转型

1.将子类对象/指针赋给父类指针的语法称为“向上转型”,也是隐式的

2.继承是向上转型的前提,向上转型的目的是为了实现多态的指针

3.向上转型有副作用:指针无法访问下级对象的成员(除非发生了重写)

向下转型

1.将父类型指针赋给子类型指针的语法称为“向下转型”,需要显示的强制转换,通常伴随着instanceof做类型判断,否则可能出现ClassCastException(类型转换异常)

2.指针向下转型为子类类型,就可以访问子类对象中的特有成员了(非重写的成员方法)

访问权限修饰符

修饰符当前类同包子类其他包
private私有的可见√不可见×不可见×不可见×
(default)默认的可见√可见√不可见×不可见×
protected受保护的可见√可见√可见√不可见×
public公有的可见√可见√可见√可见√

private的特点:只有本类可见

(default)的特点:只有同包可见

protected的特点:子类可见

public的特点:任何地方都可见

抽象类和接口的区别

1.接口也是一种源代码文件

        定义类的关键字是class

        定义接口的关键字是interface

2.接口的出现让java也能够实现多继承的,一个类只能继承一个父类,但是可以继承多个接口

        子类继承父类,关键字是extends

        子类实现/扩展接口,关键字是implements

3.接口与抽象类进行比较

相同点:

        1.都可以作为指针的类型,实现多态指针

        2.都不可以实例化

不同点:

        1.抽象类用class定义,接口用interface定义

        2.抽象类用extends继承,接口用implements实现

        3.子类只能单继承,接口可以多继承(实现)

        4.虽然两者都不可以被实例化,但是抽象类可以有构造方法,接口不可以有构造方法

        5.抽象类可以有抽象方法,也可以有具体方法,接口只能有抽象方法,而且接口中使用 的方法默认是“public abstract”修饰的

        6.抽象类可以有成员变量,接口不能有成员变量,只能有静态常量

final   修饰符 - 最终的

修饰变量,变量的值不可以修改

修饰变量,称为常量,值不可以修改

修饰方法,称为最终方法,方法不可以被子类重写

修饰类,称为最终类,类不可以被继承 

abstract 关键字是否可以与final同时出现

例如:能不能同时用abstract和final修饰类或方法

答案是不能,原因是:

        1.abstract修饰的类称为抽象类,抽象类不能被实例化,只能被继承,而final是阻止类被继承

        2.abstract修饰的方法称为抽象方法,抽象方法必须让子类重写,而final是阻止子类重写

final修饰的变量真的不能被改变吗

        如果final修饰的变量是基本数据类型,指向常量池,那么值不可以被修改

        如果final修饰的变量是引用数据类型,指向堆,那么指针不可以修改,但是指针指向的对象内的成员可以改

如何理解接口?如何理解面向接口编程

代码中存在依赖和调用关系,应该面向接口编程

调用方    -  被调用方

 

 被调用方提供接口

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码老祖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值