面向对象进阶—(多态、包和final、权限修饰符和代码块、抽象类和抽象方法)

 一、多态

1、认识多态

①什么是多态?

同类型的对象,表现出的不同形态。

多态的表现形式 

父类类型  对象名称 =子类对象;

③多态的前提

  • 有继承关系
  • 有父类引用指向子类对象                   Fu  f =new Zi ( ) ;
  • 有方法重写

register(s);

register(t);

register(a);

public static void register( Person p){

               p.show( ); //可以根据不同的对象调用不同的方法

}

⭐当我们调用方法的时候方法的参数是一个类的名字,此时可以传递这个类所有的子类对象

好处:使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。

2、⭐多态调用成员的特点

  • 变量调用:编译看左边,运行也看左边。
  • 方法调用:编译看左边,运行看右边。 

理解

Animal a = new Dog( );

用a去调用变量和方法,a是Animal类型的,所以默认从Animal这个类中去找

成员变量:在子类的对象中,会把父类的成员变量也继承下去的。

                                             父:name    子:name

成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。

 3、多态的优势和弊端

①多态的优势

  • 在多态形式下,右边对象可以实现解耦合,便于扩展和维护。

Person p = new Student( ); //只需改变红色的部分

p.work;  //业务逻辑发生改变时,后续代码无需修改

  • ⭐⭐定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。

②多态的弊端——不能调用子类的特有功能

解决方案:变回子类类型就可以了    例如:  Animal a = new Dog( );——> Dog d =new Dog( );

  -------------------------------------------------------------------  a.eat( );                  ——>d.lookhome( );

 有一个判断使类型转化异常少出现一些 ——⭐⭐判断关键字   instanceof

if(a instanceof Dog){   

     Dog d=(Dog) a;

     d.lookHome( );

}else if(a instanceof Cat){   

     Cat d=(Cat) a;

    c.catchMouse( );

}else{

      System.out.printIn("没有这个类型,无法转换");

}

//新特性

//先判断a是否为Dog类型,如果是,则强转成Dog类型,转换之后变量名为d

//如果不是,则不强转,结果直接是false

if(a instanceof Dog d){

      d.lookHome( );

}else if(a instanceof Cat c){

      c.catchMouse( );

}else{

      System.out.printIn("没有这个类型,无法转换");

}

③引用数据类型的类型转换,有几种方式?  

自动类型转换、强制类型转换

Person p =new Student( );         自动类型转换

Student s =(Student)p;               强制类型转换

④强制类型转换能解决什么问题?

  • 可以转换成真正的子类类型,从而调用子类独有功能。
  • 转换类型与真实对象类型不一致会报错
  • 转换的时候用instanceof关键字进行判断

二、包和final

1、什么是包?

①包的作用? 

包就是文件夹。用来管理各种不同功能的Java类,方便后期代码维护

②包名的规则:

  • 公司域名反写+包的作用,需要全部英文小写,见名知意。 

package com.itztt.domain;

public class Student{                                            全类名/全限定名

            私有化成员变量                      com.itheima.domain.Student

            构造方法                                          全类名 =   包名   +    类名        

            成员方法

}

使用其他类的规则

使用其他类时,需要使用全类名。

import com.itztt.domain.Student;

public class Test{   

          public static void main(String[ ] args){

                            String s = new Student( );

           }

}

 ③什么时候需要导包?什么时候不需要导包?

  •  使用同一个包中的类时,不需要导包。
  • 使用java.lang包中的类时,不需要导包。
  • 其他情况都需要导包。
  • 如果同时使用两个包中的同名类,需要用全类名。(了解,很少出现)

 2、final

  • final修饰 方法:表明该方法是最终方法,不能被重写
  • final修饰 :表明是最终类,不能被继承
  • final修饰 变量:叫做常量,只能被赋值一次

①常量

实际开发中,变量一般作为系统的配置信息,方便维护,提高可读性。

常量的命名规范:

  • 单个单词:全部大写
  • 多个单词:全部大写,单词之间用下划线隔开 

细节:

  • final修饰的变量是基础类型:那么变量存储的数据值不能发生改变。 
  • final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,对象内部的可以改变。 

 核心:

             常量记录的数据是不能发生改变的。

 

三、权限修饰符和代码块

1、权限修饰符的分类 

有四种作用范围由小到大(private<空着不写<protected<public)

                                                         缺省/默认

修饰符同一个类中

同一个包中

其他类

不同包中的

子类

不同包下的

无关类

private        √
空着不写        √      √
protected        √       √         √
public        √        √         √          √

 实际开发中,一般只用private和public

  • 成员变量私有
  • 方法公开

特例:如果方法中的代码是抽取其他方法中共性代码,这个方法一般也私有。

2、代码块 

  • 局部代码块
  • 构造代码块
  • 静态代码块

public class Text{

              public static void main(String[ ] args){

                         {

       代码块            int a = 10;

                              System.out.pringtIn(a);

                          }

               }

}

① 局部代码块

 提前结束代码的生命周期    

(已淘汰)

public class Text{

              public static void main(String[ ] args){

                         {

     局部代码块            int a = 10;                           

                              System.out.pringtIn(a);                       

                          }

               }

}

②构造代码块

1.写在成员位置的代码块

2.作用:可以把多个构造方法中重复的代码抽取出来              优先于构造方法执行

3.执行时机:我们在创建本类对象的时候会先执行构造代码块再执行构造方法

                  当多个构造方法有重复代码时,构造方法就淘汰了

弊端:创建一个对象重复一次空参

 静态代码块   (重点)

                             现代代码块

格式:static{ }

特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次

使用场景:在类加载的时候,做一些数据的初始化的时候使用。

 

四、抽象类和抽象方法

①抽象方法

1、抽象方法:将共性的行为(方法)抽取到父类之后。由于每一个子类执行的内容是不一样,所以,在父类中不能确定具体的方法体。该方法就可以定义为抽象方法

2、抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类

 ②⭐抽象类和抽象方法的定义格式

  • 抽象方法的定义格式:

                  public abstract 返回值类型 方法名(参数列表);

  • 抽象类的定义格式:

                  public abstract class 类名{ }

 ③抽象类和抽象方法的注意事项

  • 抽象类不能实例化                       抽象类不能创建对象
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 可以有构造方法
  • 抽象类的子类

                要么重写抽象类中的所有抽象方法

                要么是抽象类——还要有一个子类去重写

练习——编写带有抽象类的标准Javabean类

青蛙frog                    属性:名字,年龄                    行为:吃虫子,喝水

狗Dog                       属性:名字,年龄                    行为:吃骨头,喝水

山羊Sheep                属性:名字,年龄                    行为:吃草,喝水

Animal类 

 

Dog类

Frog类

Sheep类

测试类

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值