多态、内部类、代码块详解 2020.05.05(终于搞清楚多态怎么用了!!)

1.多态

1.1多态的概念
  • 概念

    ​ 一个对象可以表现多种形态,这就叫做是多态。

    ​ 比如:我们可以说猫是一只猫,我们也可以说猫是一个动物

  • java中多态的前提

    • 要有继承extends或者实现implements关系
    • 体现多态要有方法重写
    • 要有父类引用指向子类对象
  • 示例代码

    //创建对象
    Cat c = new Cat();
    
    //要有父类引用指向子类对象
    Animal a = new Cat();
    
1.2多态的成员访问特点
  • 成员变量

    ​ 编译看左边(父类),运行看左边(父类)

  • 成员方法

    ​ 编译看左边(父类), 运行看右边(子类)

  • 代码演示

    //动物
    public class Animal {
    
        String name = "王健林";
    
        public void method(){
            System.out.println("父类的方法");
        }
    }
    
    //猫
    public class Cat extends Animal{
    
        String name = "王思聪";
    
        public void method(){
            System.out.println("子类的方法");
        }
    }
    
    public class Demo {
        public static void main(String[] args) {
    
            //创建对象
            Cat c = new Cat();
    
            //要有父类引用指向子类对象
            Animal a = new Cat();
    
            //编译看左边(父类),运行看左边(父类)
            System.out.println(a.name);
    
            //编译看左边(父类), 运行看右边(子类)
            a.method();
        }
    }
    
1.3多态的好处和弊端
  • 弊端

    多态情况下,不能调用子类的特有方法

    //要有父类引用指向子类对象
    Animal a = new Cat();
    
    //不能调用子类的特有内容
    a.catchMouse();
    
  • 好处

    提高了代码的扩展性

    public class Demo多态的好处 {
    
        public static void main(String[] args) {
            //调用方法
            method(new Cat());
    
            method(new Dog());
        }
    
        //不使用多态,需要定义无数个方法。。。。。。
        /*
        //接受猫类型
        public static void method(Cat c){     //相当于  Cat c = new Cat();
        }
        //接口狗类型
        public static void method(Dog d){     //相当于  Dog d = new Dog();
        }
        */
    
        //使用多态
        //一个方法可以接受任意动物的子类,这个方法提高了代码扩展性
        public static void method(Animal a){   //相当于 Animal a = new Cat();
                                                //     Aniaml a = new Dog();
        }
    
    }
    
1.4接口体现多态的案例
  • 笔记本案例要求:

    ​ 定义USB接口,接口中定义yong()方法

    ​ 定义Computer电脑类,类中定义使用USB设备的方法use(USB usb)

    ​ 定义Mouse鼠标类,类中实现USB接口,供电脑使用

    ​ 定义KeyBoard键盘类,类中实现USB接口,供电脑使用

    ​ 定义测试类进行测试电脑的方法

  • 示例代码

1.5多态的转型
  • 向上转型

    把子类类型转成父类类型

    Animal a = new Cat();    //把Cat类型转成Animal类型
    
  • 向下转型

    把父类类型转成子类类型

    //子类类型 变量名 = (子类类型)父类类型对象;
    Cat c = (Cat) a;
    作用:
    	为了调用子类的特有方法
    
  • 类型转化异常

    ClassCastException类型转换异常
    
    做了不正确的向下转型时会出现这个异常
    
  • 关键字instanceof

    • 作用

      instanceof可以判断一个对象是否是某种类型,可以避免出现类型转换异常

    • 格式

      对象 instanceof 类型
      
      如果这个对象是后面这种类型就会返回true
      如果这个对象不是后面这种类型就会返回false
      我们就可以使用这个关键字对对象进行判断
      
    • 示例代码

      public class Demo转型问题的解决 {
      
          public static void main(String[] args) {
              //小王写的:
              Animal a = new Cat();
      
              //---------------------------------------
      
              //老王写的:
              //小王告诉老王a动物是一个猫
              //老王在转换之前先做判断
              if(a instanceof Cat){
                  //向下转型
                  Cat c = (Cat)a;
                  c.catchMouse();
              }
      
              //作用:避免类型转换异常的发生!!!
          }
      }
      

2.内部类

2.1内部类的概念
  • 概念:

    内部类就是定义类类里面的类,比如每个人都有心脏。人是一个类,心脏也是一个类,心脏就是人的内部类。

  • 分类:

    • 成员内部类
    • 局部内部类
      • 匿名内部类
2.2成员内部类
  • 概念:

    定义在类中方法外的内部类就是成员内部类

  • 在测试类中创建对象的方式:

    外部类名.内部类名  变量名 = new 外部类().new 内部类();
    
  • 变量重名时的访问:

    访问外部类的成员变量:
    	外部类名.this.变量名
    
  • 示例代码:

//外部类
//外部类
public class AAA {
    //外部类的成员变量
    String name = "周星驰";
    //成员内部类
    class BBB{
        //内部类的成员变量
        String name = "大鹏";
        //BBB的方法
        public void method(){
            //局部变量
            String name = "柳岩";

            System.out.println(name);       	//柳岩   就近原则
            System.out.println(this.name);  	//大鹏   this用来区分局部变量和成员变量的重名
            System.out.println(AAA.this.name);  //周星驰
        }
    }
}

//测试类
public class Demo成员内部类测试 {
    public static void main(String[] args) {

        //创建对象
        AAA a = new AAA();


        //创建内部类对象
        //外部类名.内部类名  变量名 = new 外部类().new 内部类();
        AAA.BBB b = new AAA().new BBB();
        //调用内部类方法
        b.method();
    }
}
2.3局部内部类
  • 概念:

    定义在方法中的内部类就叫做是局部内部类

    //外部类
    public class CCC {
    
        //定义方法
        public void method(){
            //外部类的局部变量
            int a = 10;
            
            //局部内部类
            class DDD{
                //内部类的方法
                public void show(){
                    System.out.println("内部类的方法");
                }
            }
        }
    }
    
  • 作用:

    局部内部类没什么大作用,因为局部限制了他的使用范围,只能在当前方法中使用,所以这个东西真没什么使用场景。

  • 局部内部类的小问题:

    • 在局部内部类中访问了外部类的局部变量,那么这个变量就变成了final变量,不能被修改。
    //外部类
    public class CCC {
    
        //定义方法
        public void method(){
            //外部类的局部变量
            //如果在局部内部类中访问了外部类的局部变量,那么这个变量会自动被final修饰
            int a = 10;
            
            //局部内部类
            class DDD{
                //内部类的方法
                public void show(){
                    System.out.println(a);
                    //修改a的值
                    //被final修饰的变量不能修改
                    a = 20;
                }
            }
        }
    }
    
2.4匿名内部类
  • 概念

    ​ 没有类名的内部类就是匿名内部类

  • 格式

    new 类名/接口名(){
        方法重写
    };
    
  • 代码演示

    //写法一:
    //这个代表Animal的子类对象,子类叫啥??没有类名
    Animal a = new Animal(){
        @Override
        public void eat() {
            System.out.println("匿名内部类吃饭方法");
        }
    };
    
    //写法二:
    //调用方法
    method(new Animal(){
        @Override
        public void eat() {
            System.out.println("匿名内部类吃饭方法");
        }
    });
    
  • 本质

    ​ 匿名内部类的本质其实是类或接口的子类对象。

  • 匿名内部类作用

    ​ 作用是简化代码。之前需要单独定义一个类,现在不用单独定义类。

    ​ 匿名内部类可用可不用。对于初学者来说因为格式复杂阅读性低所以不习惯用,但是在工作中经常使用匿名内部类。因为对代码熟悉了之后,觉得代码写的越简单越好。

2.5内部类小结

​ 成员内部类【我们不写,java源码中可以看到】

​ 局部内部类【我们不写java中也很少,了解即可】

​ 匿名内部类【重点】

​ 每一个内部类也都会有一个单独的.class文件

3.权限修饰符

3.1四个权限修饰符

public > protected > 空的 > private

3.2访问范围
本类中本包中不同包的子类中不同包中
publicYYYY
protectedYYY
空的YY
privateY
  • 代码演示
package com.itheima_07;

public class AAA {
    //公共的
    public void method1(){
        System.out.println("public");
    }
    //受保护的
    protected void method2(){
        System.out.println("protected");
    }
    //空的
    void method3(){
        System.out.println("空的");
    }
    //私有的
    private void method4(){
        System.out.println("private");
    }

    //当前类
    public void show(){
        method1();
        method2();
        method3();
        method4();
    }
}

public class BBB {
    public static void main(String[] args) {

        AAA a = new AAA();

        a.method1();
        a.method2();
        a.method3();
        //a.method4();
    }
}

package com.itheima_08;
import com.itheima_07.AAA;

//不同包下的子类
//可以使用public和protected的方法
public class CCC extends AAA{

    public void show(){
        method1();
        method2();
        //method3();
        //method4();
    }
}

//不同包
public class DDD {
    public static void main(String[] args) {
        AAA a = new AAA();
        a.method1();
        //a.method2();
        //a.method3();
        //a.method4();
    }
}
3.3 权限修饰符的作用位置【不用记】

​ 类:public 空的

​ 成员变量:四个都能用

​ 成员方法:四个都能用

​ 构造方法:四个都能用

​ 局部变量:没有权限修饰符

4.代码块

4.1静态代码块
  • 格式:

    static{
       要执行的代码 
    }
    
  • 执行时机:

    在当前类第一次被使用的时候静态代码块会执行,且只执行一次

  • 代码演示:

    public class AAA {
    
        static int a = 10;
        //静态代码块
        //在AAA类第一次被使用的时候,静态代码块会自动执行
        static{
            System.out.println("静态代码块");
        }
    }
    
    public class Demo测试类 {
        public static void main(String[] args) {
    
            //创建对象
            //AAA a1 = new AAA();
            //AAA a2 = new AAA();
    
            System.out.println(AAA.a); //10
        }
    }
    
    执行效果:
    	静态代码块
    	10
    
  • 使用场景:

    如果有些代码只需要执行一次且需要在别的代码之前执行,就可以放在静态代码块中,比如加载驱动。

4.2构造代码块
  • 格式:

    在类中方法外:
    {
       里面可以写代码;
    }
    
  • 执行时机:

    在构造方法执行的最开始先执行构造代码块

  • 代码演示:

    public class BBB {
    
        String name;  //姓名
        int age;      //年龄
    
        //构造代码块
        //会在每个构造方法执行时候先执行构造代码块
        {
            System.out.println(1);
            System.out.println(2);
            System.out.println(3);
        }
        //空参构造
        public BBB() {
            
        }
    
        //有参构造
        public BBB(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    public class Demo构造代码块测试 {
    
        public static void main(String[] args) {
    
            //使用空参构造创建对象
            BBB b = new BBB();
    
            //使用有参构造创建对象
            BBB b2 = new BBB("柳岩",36);
        }
    }
    
    执行结果:
    	1
    	2
    	3
    	1
    	2
    	3
    
  • 使用场景:

    多个构造方法中有相同的代码,为了提高代码复用性,可以把相同的代码抽取到构造代码块中

4.3局部代码块
  • 格式:

    方法中:
    {
        可以写代码;
    }
    
  • 作用:

    限制变量的作用域,节约内存空间。

  • 代码演示:

    public class Demo局部代码块测试 {
    
        public static void main(String[] args) {
    
            int a = 10;
            //局部代码块
            //变量b的作为范围只能在局部代码块中
            {
                int b = 20;
            }
    
            System.out.println(a);
            //System.out.println(b);  超出作用域就不能使用
    
    
            //在java中为了节约内存设计过很多技术点,但是现在内存不值钱了,所以这些技术也就慢慢不用了.
    
        }
    }
    
4.4代码块执行顺序演示
public class CCC {
    //静态代码块
    static{
        System.out.println(1);
    }

    //构造代码块
    {
        System.out.println(2);
    }

    //构造方法
    public CCC(){
        System.out.println(3);
    }
}

public class Demo练习测试 {
    public static void main(String[] args) {

        //创建对象
        CCC c = new CCC();

        CCC c2 = new CCC();
    }
}

执行效果:
	1
	2
	3
	2
	3
	

总结

多态
	成员访问特点
		成员变量【记】
		成员方法【记】
	优缺点
		缺点【记】
		优点【记】
		
	类型转换
		向上转型【记】
		向下转型【记】
		ClassCastException异常【理解不用记】
		instanceof【练】
	笔记本案例【练】
	
内部类
	成员内部类【理解就ok】
	局部内部类【不用】
	匿名内部类【记】
	
权限修饰符
	四个权限修饰符
		public 【常用】
		protected
		空的
		private【常用】
		
代码块
	静态代码块【记】
	构造代码块【不常用】
	局部代码块【赶紧忘掉】
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值