多态
可以理解为事物存在的多种体现形态。
举例: 人:男人,女人; 动物:猫,狗等
Object p = new Person(); 实例p只能调用Object类的方法,而不能调用Person里的定义的方法
instanceof 运算符:用于判断是否可以强制转换
instanceof 前一个操作通常是一个引用变量,后一个操作通常是一个类,用于判断前面的对象是否是后一个类或者其子类的实例对象。
1. 多态的体现
- 父类的引用指向了自己的子类对象
- 父类的引用也可以接收自己的子类对象
2. 多态的前提
- 必须是类与类之间有关系。要么继承,要么实现
- 存在覆盖
3. 多态的好处:
- 多态大大提高了程序的扩展性
4. 多态的弊端:
- 提高了扩展性,但是只能使用父类的引用访问父类中的成员。
举例:
package 多态;
abstract class Animal{
//动物都具备吃的方法,且吃的东西不一样,用抽象
abstract void eat();
}
class Cat extends Animal{
@Override
void eat() {
System.out.println("吃鱼!");
}
// 特有的方法
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
@Override
void eat() {
System.out.println("吃骨头");
}
// 特有的方法
public void kaijia(){
System.out.println("看家");
}
}
public class DuoTaiDemo {
public static void main(String[] args) {
// Animal cat = new Cat();
// cat.eat();
// cat.catchMouse(); // 不能被调用
fun(new Cat());
fun(new Dog());
/*
* 吃鱼!
吃骨头
* */
}
// 多态:只能调用父类的方法
public static void fun(Animal a){
a.eat();
}
}
向下转型
abstract class Animal{
//动物都具备吃的方法,且吃的东西不一样,用抽象
abstract void eat();
}
class Cat extends Animal{
void eat() {
System.out.println("吃鱼!");
}
// 特有的方法
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
void eat() {
System.out.println("吃骨头");
}
// 特有的方法
public void kaijia(){
System.out.println("看家");
}
}
public class DuoTaiDemo2 {
public static void main(String[] args) {
fun(new Cat());
fun(new Dog());
/*
吃鱼!
抓老鼠
吃骨头
看家
* */
}
// 多态:始终都是子类对象在发生变化
public static void fun(Animal a){ // Animal a = new Cat(); // 向上转型
//调用子类的方法
if(a instanceof Cat){
Cat cat = (Cat)a; // 向下转型
cat.eat();
cat.catchMouse();
}else if( a instanceof Dog){
Dog dog = (Dog)a;
dog.eat();
dog.kaijia();
}
}
}
多态示例:
/*
基础班学生:
睡觉,学习
高级班学生:
睡觉,学习
可将这两类事物进行抽象
*
* */
abstract class Student{
public abstract void study();
public void sleep(){
System.out.println("躺着睡");
}
}
//将学生要做的事封装成一个类
class DoStudent{
public static void doSome(Student s){
s.study();
s.sleep();
}
}
class BaseStudent extends Student{
public void study() {
System.out.println("我们学习java基础");
}
// 重写父类方法
public void sleep(){
System.out.println("做着睡");
}
}
class AdvStudent extends Student{
public void study() {
System.out.println("我们学习java进阶");
}
// 重写父类方法
public void sleep(){
System.out.println("没法睡");
}
}
// 如果要添加其他学生只需继承父类即可
public class DuoTaiDemo3 {
public static void main(String[] args) {
DoStudent.doSome(new BaseStudent());
DoStudent.doSome(new AdvStudent());
}
}
多态中成员的特点:
package test;
class Fu{
static int num = 5;
void method1(){
System.out.println("fu method_1");
}
void method2(){
System.out.println("fu method_2");
}
static void method4(){
System.out.println("fu method_4");
}
}
class Zi extends Fu{
static int num = 10;
// 重写父类的方法
void method1(){
System.out.println("zi method_1");
}
void method3(){
System.out.println("zi method_3");
}
static void method4(){
System.out.println("zi method_4");
}
}
public class DuoTaiDemo4 {
public static void main(String[] args) {
Fu f = new Zi();
f.method1(); // zi method_1
f.method2(); // fu method_2
System.out.println(f.num); //5 父类的
Zi z = new Zi();
System.out.println(z.num); // 10 子类的
f.method4(); // fu method_4
z.method4(); // zi method_4
}
}
/*
*
结论:
在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。
*/
多态的扩展性 之 主板示例(重点**)
// PCI 接口
interface PCI{
public abstract void open();
public abstract void close();
}
// 主板使用接口
class MainBorad{
public void run(){
System.out.println("主板开始运行");
}
// PCI p 多态和接口 提高扩展性
public void usePCI(PCI p){
if(p!=null){
p.open();
p.close();
}
}
}
// 网卡实现接口
class NetCard implements PCI{
public void open(){
System.out.println("网卡启动。。。");
}
public void close(){
System.out.println("网卡退出。。");
}
}
public class DuoTaiDemo5 {
public static void main(String[] args) {
MainBorad borad = new MainBorad();
borad.run(); // 主板启动
borad.usePCI(new NetCard()); // 启动接口,插入网卡
}
}
// 每当需要插入一个硬件,只需实现PCI接口即可
多态的扩展性 之 数据库的连接(重点**)
// 定义一个接口
interface UserInfoDao{
public abstract void add();
public abstract void delete();
}
class UserByJDBC implements UserInfoDao{
public void add() {
System.out.println("连接数据库");
System.out.println("添加数据");
System.out.println("关闭数据库连接");
}
public void delete() {
System.out.println("连接数据库");
System.out.println("删除数据");
System.out.println("关闭数据库连接");
}
}
class UserByMybaties implements UserInfoDao{
public void add() {
System.out.println("连接数据库");
System.out.println("添加数据");
System.out.println("关闭数据库连接");
}
public void delete() {
System.out.println("连接数据库");
System.out.println("删除数据");
System.out.println("关闭数据库连接");
}
}
public class DBOperator {
public static void main(String[] args) {
UserInfoDao uidao= new UserByJDBC();
uidao.add();
uidao.delete();
UserInfoDao uidao1= new UserByMybaties();
uidao1.add();
uidao1.delete();
}
}
Object 类
Object:是所有对象的直接后者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。