【无标题】

day03 【修饰符,内部类,参数传递】

今日内容介绍

final关键字
static关键字
访问权限
内部类
引用类型参数

第一章 final关键字

1.1 final的概述【重点】

final关键字: 代表最终的,不可改变
可以修饰的内容:
1.:
    不可以被继承,不能够有子类
    看: MyStringMyArrayList
    称之为太监类: 不能有子类,但是有父类
2.方法:
    不能被子类覆盖重写

3.变量:   只能赋值一次,不可以进行第二次赋值,变量的值是不可以发生改变的     常量

1.2 final修饰的类的特点【重点】01

final修饰的类的特点
    该类不可以被继承,不能有子类
//父类
public final class Fu01 extends Object {
    public void method() {
        System.out.println("Fu01...method...");
    }
    public void show() {
        System.out.println("Fu01...show...");
    }
}
/*
    子类: Fu01被final修饰以后,不能被继承,不能有子类
    太监类,没有子类,但是有父类
 */
public class Zi01 /*extends Fu01*/ {
}

//String类被final修饰,不能有子类
public class MyString /*extends String*/ {
}
//ArrayList集合没有被final修饰,可以被继承
public class MyArrayList extends ArrayList {
    public MyArrayList(int initialCapacity) {
        super(initialCapacity);
    }

    public MyArrayList() {
    }

    public MyArrayList(Collection c) {
        super(c);
    }
}

1.3 final修饰的方法的特点【重点】02

final修饰的方法: 不能被子类覆盖重写

//父类
public class Fu02 {
    public final void method() {
        System.out.println("Fu02...method...");
    }

    public void show() {
        System.out.println("Fu02...show...");
    }
}
//子类
public class Zi02 extends Fu02 {
    /*
    //父类method方法被final修饰,子类不能进行覆盖重写
    @Override
    public void method() {
        System.out.println("Zi02...method...");
    }*/

    //子类如果可以重写父类的方法,
    //子类重写后的方法可以添加final关键字
    @Override
    public final void show() {
        System.out.println("Zi02...show...");
    }
}
//测试类
public class Demo02FinalMethod {
    public static void main(String[] args) {
        //创建子类对象
        Zi02 zi02 = new Zi02();

        zi02.method();
        zi02.show();
    }
}

1.4 final修饰的变量的特点【重点】03

final修饰变量:   
	1.特点: 只能赋值一次,不可以进行第二次赋值,变量的值是不可以发生改变的     常量
    2.修饰局部变量(方法内部定义的变量):
    	(1)基本类型: 基本类型变量中存储的具体的数字是不可以被改变的

    	(2)引用类型: 存储的对象的地址值,final修饰后,说明变量存储的对象的地址值是不可以被改变的
                            但是该地址代表的内存空间中的内容是可以改变的

    3.成员变量:MyClass03 认为默认值无效,要么显式赋值,要么构造方法中赋值
        (1)定义未赋值:
            所有构造方法中,必须完成对final修饰的变量的赋值
            所有成员方法中,不能修改final修饰的变量的值

        (2)定义并赋值:
            所有构造方法/成员方法中,不能修改final修饰的变量的值
//final修饰局部变量
public class Demo03FinalVar {
    public static void main(String[] args) {
        final int num = 10;//定义变量,并第一次赋值
        System.out.println(num);//10
        //num = 20;//错误: 不能进行第二次赋值(不能修改变量中的值)

        final int num2;//定义变量,未赋值

        num2 = 100;//正确: 第一次赋值

        System.out.println(num2);//100

        //num2 = 1000;//错误: 不能进行第二次赋值(不能修改变量中的值)

        System.out.println("--------------");

        //创建Student类的对象
        final Student stu = new Student("张三", 18);

        stu.show();

        //stu被final修饰,存储的地址值是不可以发生改变的
        //stu = new Student("李四",28);


        stu.setName("李四");
        stu.setAge(28);

        stu.show();
        System.out.println("-------------");

        //数组名保存地址值,被final修饰后,地址值不可以被改变
        final int[] arr = new int[]{10,20,30};
        System.out.println(Arrays.toString(arr));

        //arr = new int[]{100,200,300};

        //把每个元素扩大10被
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 10;
        }
        System.out.println(Arrays.toString(arr));
    }
}
//final修饰成员变量
public class Demo03FinalVar2 {
    String name;
    //定义未赋值
    final int num;
    //定义并赋值
    final int num2 = 20;
    //空参构造
    public Demo03FinalVar2() {
        num = 10;
        //错误: 第二次赋值
        //num2 = 200;
    }
    //满参构造
    public Demo03FinalVar2(String name) {
        this.name = name;
        num = 10;
        //错误: 第二次赋值
        //num2 = 200;
    }
    //成员方法
    public void show() {
        //num = 100;
        //错误: 第二次赋值
        //num2 = 200;
    }
}

1.5 权限修饰符 04

在java中有四种权限修饰符:范围从大到小分别是:public、protect、default(friendly)private
作用域publicprotected默认(什么都不写)private
在同一个类中
在同一个包中(子类/无关类)
不同包的子类
不同包的无关类
//父类: com.itheima04包中
public class Fu04 {
    //用四种权限定义不同的变量
    public int a = 1;
    protected int b = 11;
    int c = 111;
    private int d = 1111;

    //成员方法
    //在同一个类中,四种权限都可以使用
    public void show() {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }
}
//子类: com.itheima04包中
//同一个包中的子类: 除了private以外,另外三种权限都可以使用
public class Zi04 extends Fu04 {

    public void method() {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        //System.out.println(d);
    }
}
//无关类: com.itheima04包中
public class Demo04QuanXian {
    public static void main(String[] args) {
        //创建Fu04类的对象
        Fu04 fu04 = new Fu04();
        System.out.println(fu04.a);
        System.out.println(fu04.b);
        System.out.println(fu04.c);
        //同一个包中的无关类: 除了private以外,另外三种权限都可以使用
        //System.out.println(fu04.d);
    }
}
//不同包子类:com.itheima04.sub包中
//不同包的子类: 除了private和默认权限以外,另外两种权限都可以使用
public class Zi0402 extends Fu04 {
    public void fun() {
        System.out.println(a);
        System.out.println(b);
        //System.out.println(c);
        //System.out.println(d);
    }
}
//不同包无关类:com.itheima04.sub包中
//在不同的包的无关类: 只有public权限可以使用,其余权限不能用
public class Demo04WuGuan {
    public static void main(String[] args) {
        //创建Fu04类的对象
        Fu04 fu04 = new Fu04();
        System.out.println(fu04.a);
        //System.out.println(fu04.b);
        //System.out.println(fu04.c);
        //System.out.println(fu04.d);
    }
}

第二章 static关键字

2.1 static关键字的概念【重点】

static关键字:
1.概念:
    被该类的所有对象共享使用,不依赖于某个具体的对象,和对象无关,依赖于类,在内存中唯一只有一份

2.类的加载过程:
    第一次使用new创建Student类的对象时,首先检查.class文件,是否被加载到方法区中,如果没有,Student类的.class文件加载到方法区中(此时还没有对象),如果.class文件中有static静态修饰的内容,
    会把static静态修饰的内容,加载方法区的静态区中,并且要完成静态成员的初始化然后: 才进行对象的创建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WMn9VqZ4-1643037451879)(img/1600693937764.png)]

2.2 static修饰成员变量的使用【重点】

static修饰修饰成员变量(类变量: 依赖于类,与对象无关)
1.定义格式:
    static 数据类型 变量名称 = 数据值;

2.使用格式:
    类名.静态成员变量名称;        推荐使用
    对象名.静态成员变量名称;      不推荐使用

2.3 static修饰成员方法的使用【重点】05

static修饰成员方法(类方法: 依赖于类,与对象无关)
1.定义格式:
    public static 返回值类型 方法名称(参数列表...) {...}

2.使用格式:
   类名.静态成员方法名称(...)        推荐使用
    对象名.静态成员方法名称(...)      不推荐使用
    
3.注意:
	静态成员变量也有默认初始化值

public class JavaEE372Student {
    String name;//不能使用static修饰: 属于每个对象的特有数据
    static String room;//使用static修饰: 属于所有对象的共享数据

    //定义静态方法
    public static void show() {
        System.out.println("班级: "+room);
    }
}
//测试类
public class Demo05Static {
    public static void main(String[] args) {
        System.out.println(JavaEE370Student.room);//null
        //创建JavaEE372Student类的对象
        JavaEE372Student stu = new JavaEE372Student();
        //不推荐使用对象调用静态成员
        System.out.println(stu.room);//null

        System.out.println("---------");
        //给静态成员赋值
        JavaEE372Student.room = "HMTBD1002";
        System.out.println(JavaEE372Student.room);//HMTBD1002
        System.out.println(stu.room);//HMTBD1002

        System.out.println("---------");
        JavaEE372Student stu2 = new JavaEE372Student();

        stu2.room = "HMTBD1003";

        System.out.println(stu.room);//HMTBD1003
        System.out.println(stu2.room);//HMTBD1003
        System.out.println(JavaEE372Student.room);//HMTBD1003

        System.out.println("---------");
        //调用静态成员方法
        //推荐使用类名调用
        JavaEE372Student.show();//班级: HMTBD1003

        //不推荐使用对象调用
        stu.show();//班级: HMTBD1003
    }
}

2.4 静态的注意事项【了解】06

静态的内容只能使用静态的内容,不能使用非静态的内容
1.解释:
	(1)静态当中不能使用非静态
	(2)静态的内容,是最先被加载到内存方法区中的静态区中,并完成初始化,但是此时没有对象(非静态的内容存在			于对象中)既然没有对象,就不能使用非静态的内容
	(3)静态(先人),非静态(后人)

2.静态的注意事项
	(1)静态方法可以直接访问静态变量和静态方法。
	(2)静态方法不能直接访问非静态成员变量或成员方法。反之,成员方法可以直接访问静态变量或静态方法。
	(3)静态方法中,不能使用this关键字。
//此类只针对黑马的老师
public class HMTeacher {
    String name;//不能使用static修饰: 属于每个对象的特有数据
    static String country = "CHINA";//使用static修饰: 属于所有对象的共享数据

    //静态方法
    public static void show() {
        //静态方法中可以直接使用静态成员变量
        //静态的内容是统一最先被加载到内存的静态区的
        System.out.println("国籍: "+country);
        /*
            静态内容是最先被加载到内存的静态区中的,此时没有对象(哪来的this),
            而非静态的成员变量存在于对象中,既然没有对象,就不能使用非静态内容
         */
        //System.out.println("姓名: "+name);

        //System.out.println("姓名: "+this.name);

        //调用静态
        //method方法和show方法在同一个类中,可以省略类名
        method();
        //HMTeacher.method();

        /*
            静态内容是最先被加载到内存的静态区中的,此时没有对象,
            而非静态的成员方法存在于对象中,既然没有对象,就不能使用非静态内容
         */
        //printName();

    }

    //静态方法
    public static void method() {
        System.out.println("静态方法...method...");
    }

    //非静态方法
    public void printName() {
        /*
            非静态方法必须由对象调用,对象都已经有了,
            class文件早已经被加载到内存中了,
            那静态的内容也已经被加载到内存中并初始化了
         */
        System.out.println("姓名: "+name+", 国籍: "+country);

        //调用静态方法
        show();

    }
}
//测试类
public class Demo06StaticNotice {
    public static void main(String[] args) {
        //直接使用类名调用静态方法,根本没有对象
        //HMTeacher.show();

        //创建对象
        HMTeacher ht = new HMTeacher();

        //对象调用成员方法
        ht.printName();
    }
}

2.6 静态代码块【重点】07

静态代码块
1.格式:
	static {
    	...
	}

2.特点:
    (1)假如只创建对象,静态代码块会优先于构造方法执行,唯一执行一次
    (2)静态代码块,随着类的加载而加载并唯一执行一次
    (3)完成静态成员变量的赋值
    (4)静态代码块,仍然属于静态内容,内部不能使用非静态
    (5)完成项目的初始化工作

/*
    静态代码块
    1.格式:
        static {
            ...
        }

    2.特点:
        (1)假如只创建对象,静态代码块会优先于构造方法执行,唯一执行一次
        (2)静态代码块,随着类的加载而加载并唯一执行一次
        (3)完成静态成员变量的赋值
        (4)静态代码块,仍然属于静态内容,内部不能使用非静态
        (5)完成项目的初始化工作
 */
public class Demo07StaticKuai {
    public static void main(String[] args) {
        //创建对象
        //Person p = new Person();
        //Person p2 = new Person();

        System.out.println(Person.country);
    }
}
//此类只针对咱们中国人
public class Person {
    String name;//不能使用static修饰: 每个对象的特有数据
    static String country = "CHINESE";//必须使用static修饰: 所有的对象的共享数据

    //空参构造方法
    public Person(){
        System.out.println("空参构造被执行了...");
    }

    //静态代码块
    static {
        System.out.println("静态代码块执行了...");
        //(3)完成静态成员变量的赋值
        country = "CHINA";
        //(4)静态代码块,仍然属于静态内容,内部不能使用非静态
        /*
            name属于非静态成员变量,必须由对象调用,
            但是静态代码块执行时,还没有完成对象的创建,
            所以静态代码块中不能使用非静态的内容
         */
        //System.out.println(name);
        /*
            this代表对象,但是静态代码块执行时,还没有完成对象的创建
         */
        //System.out.println(this.name);

        //(5)完成项目的初始化工作
        init();
    }

    //模拟项目初始化的方法
    public static void init() {
        System.out.println("项目正在完成初始化,需要稍等10秒钟....");
        for (int i = 10; i > 0; i--) {
            //此代码直接复制,后面多线程中讲解
            try {
                Thread.sleep(1000);//1000毫秒,程序在此处休眠1000毫秒(1秒)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i);
        }
        System.out.println("项目初始化完成,你可以尽情使用了....");
    }
}

第三章 内部类【了解】

3.1 内部类的概念

内部类概念:
	将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
	举例:
		汽车(外部类)内部有个发动机(内部类)
        人体(外部类)内部有心肝脾肺肾(内部类)
        定义一个类来描述一个事物时,该类的内部又定义了一个/多个类来描述其内部的事物
        一个东西(外部类)内部包含另外一个/多个东西(内部类)
    分类:
		1.成员内部类: 定义在外部类的成员位置(和成员变量/成员方法 地位相同)
            可以使用: public/private/static进行修饰
        2.局部内部类: 定义在外部类的方法内部,该内部类出了方法就没有用了

3.2 成员内部类的定义和使用 08

/*
成员内部类(和成员变量/成员方法 处于同一位置)
1.定义格式:
	public class 外部类名 {//外部类
        //外部类成员变量
        //外部类成员方法
        //外部类构造方法
        //成员内部类
        public class 内部类名 {
            //内部类成员变量
        	//内部类成员方法
        	//内部类构造方法
        }
    }

2.成员内部类的使用格式:
	(1)外部类要访问内部类的成员,必须要建立内部类的对象。
        外部类.内部类 对象名 = 外部类对象.new 内部类();
        外部类.内部类 对象名 = new 外部类().new 内部类();
        简单来讲: 外.内 对象名 = new 外().new 内();

    (2)内部类可以直接访问外部类的成员,包括私有成员。

3.注意:
 	(1)内部类也是类,编译后也有对应的class文件: 外部类名$内部类名.class
    (2)内部类可以使用public修饰,也可以使用private修饰,还可以使用static修饰
    (3)可以在方法内部定义内部类(局部内部类),出了方法就失效了(必须在方法内部创建内部类的对象并使用)
*/ 
public class Person {//外部类
    //外部类的成员变量
    int age;
    //外部类私有成员
    private boolean liveAble = true;//心脏是否还活着
    public class Heart {//内部类
        //内部类的成员变量
        public int num;
        //内部类构造方法
        public Heart() {
        }
        //内部类的成员方法
        public void jump() {
            if (liveAble) {
                System.out.println("我的小心脏那个扑通扑通的跳啊.....");
            } else {
                System.out.println("我的小心脏剧烈的痛呢? 来颗速效救心丸,否则哥们罢工....");
            }
        }
    }
    //外部类构造方法
    public Person() {
    }
    //外部类的set方法
    public void setAge(int age) {
        this.age = age;
    }
    public void setLiveAble(boolean liveAble) {
        this.liveAble = liveAble;
    }
}
//测试类
public class Demo08InnerClass {
    public static void main(String[] args) {
        //创建外部类对象
        Person p = new Person();
        //外部类的成员变量: 对象名.成员变量名称
        System.out.println(p.num);
        //成员内部类对象的创建格式: 外部类对象.new 内部类名称(实际参数...);
        Person.Heart h = p.new Heart();
        //调用内部类对象的成员方法
        h.jump();
        //通过外部类对象调用set方法,修改外部类成员变量的值
        p.setLiveAble(false);
        h.jump();

        //成员内部类对象的创建格式: new 外部类名称(实际参数...).new 内部类名称(实际参数...);
        Person.Heart h2 = new Person().new Heart();

        h2.jump();
        //注意: 这里又创建了一个Person对象,
        //和上面的不是一个对象,这次调用set方法,对h2不会产生影响
        new Person().setLiveAble(false);

        h2.jump();

    }
}

3.3 内部类中3个重名变量的使用 08

内部类中3个重名变量的使用
    直接写变量名: 方法内部局部变量
    this.变量名: 内部类成员变量
    Outer.this.变量名: 外部类成员变量
public class Outer {//外部类
    //外部类的成员变量
    int num = 1;
    public class Inner {//内部类
        //内部类的成员变量
        int num = 11;
        //内部类成员方法
        public void show() {
            int num = 111;
            //输出111
            System.out.println(num);//111
            //输出11
            System.out.println(this.num);//11
            //输出1
            System.out.println(Outer.this.num);//1
        }
    }
}
//测试类
public class Demo02InnerClass {
    public static void main(String[] args) {
        //创建内部类对象
        Outer.Inner inner = new Outer().new Inner();
        //内部类对象调用方法
        inner.show();
    }
}

3.4 匿名内部类引入 09

/*
需求: 调用一次FlyAble接口中的抽象方法fly
	实现步骤:
    	1.定义实现类实现FlyAble接口
    	2.实现类覆盖重写FlyAble接口的所有抽象方法
    	3.创建实现类的对象
    	4.实现类对象调用fly方法

	发现问题:
    	就为了调用一次FlyAble接口中的fly方法,我们目前需要定义实现类实现接口,
    	实现类覆盖重写接口中所有的抽象方法,创建实现类对象,实现类对象调用方法,
    	总共需要四步完成,太麻烦

	解决方案: 匿名内部类对象
*/
//定义接口
public interface FlyAble {
    //抽象方法: 飞的方法fly
    public abstract void fly();
}
//定义实现类Bird,实现接口FlyAble
public class Bird  implements FlyAble {
    //2.实现类覆盖重写FlyAble接口的所有抽象方法
    @Override
    public void fly() {
        System.out.println("鸟儿在空中自由的翱翔....");
    }
}
//测试类
public class Demo03NiMing {
    public static void main(String[] args) {
        //3.多态的方式创建实现类的对象
        FlyAble flyAble = new Bird();

        //4.实现类对象调用fly方法
        flyAble.fly();
    }
}

3.5 匿名内部类的使用 10

/*
    匿名内部类对象
    1.概念:
        是内部类的简化写法。它的本质是一个 带具体实现的 父类或者父接口的 匿名的 子类对象。

    2.作用:
        (1)是一种创建接口实现类对象的快捷方式
            把创建实现类,覆盖重写抽象方法,创建实现类对象,实现类对象调用方法这四步合成一步完成

        (2)是一种创建抽象父类的子类对象的快捷方式
            把创建子类,覆盖重写抽象方法,创建子类对象,子类对象调用方法这四步合成一步完成

    3.匿名内部类对象创建格式:
        new 抽象父类/接口(); //错误: 不能直接new抽象父类/接口的对象

        new 抽象父类/接口() {
            覆盖重写所有的抽象方法;
        }

        注意:
            (1)上面只是创建了一个抽象父类的子类对象或者接口的实现类对象
            (2)该对象目前没有名字
            (3)该对象所属的类是没有名字的
                (注意:其实有名字(外部类名$1.class),只是该名字不是我们起的,是JVM帮助我们起的)
*/      
public abstract class Animal {
    //抽象方法
    public abstract void eat();
    public abstract void sleep();
}
//抽象类,演示匿名内部类对象的使用
public class Demo10AbstractNiMing {
    public static void main(String[] args) {
        //直接创建抽象类的匿名内部类对象
        new Animal(){
            @Override
            public void eat() {
                System.out.println("小狗在吃....");
            }

            @Override
            public void sleep() {
                System.out.println("小狗在睡....");
            }
        };
        //直接创建抽象类的匿名内部类对象然后调用抽象类中定义的方法
        new Animal(){
            @Override
            public void eat() {
                System.out.println("小狗在吃....");
            }

            @Override
            public void sleep() {
                System.out.println("小狗在睡....");
            }
        }.eat();
        new Animal(){
            @Override
            public void eat() {
                System.out.println("小狗在吃....");
            }

            @Override
            public void sleep() {
                System.out.println("小狗在睡....");
            }
        }.sleep();
        //直接创建抽象类的匿名内部类对象然后调用子类特有的方法
        //没有意义
        new Animal(){
            @Override
            public void eat() {
                System.out.println("小狗在吃....");
            }

            @Override
            public void sleep() {
                System.out.println("小狗在睡....");
            }
            //特有方法
            public void kanHome() {
                System.out.println("小狗在看家....");
            }
        }.kanHome();
        //多态的方式创建抽象类的匿名内部类对象
        Animal a = new Animal() {
            @Override
            public void eat() {
                System.out.println("小猫在吃....");
            }

            @Override
            public void sleep() {
                System.out.println("小猫在睡....");
            }
            //特有方法
            public void catchMouse() {
                System.out.println("小猫在逮老鼠....");
            }
        };
        a.eat();
        a.sleep();
        //错误: 多态不能调用子类的特有方法
        //((Animal) a).catchMouse();
        //Demo10AbstractNiMing$5类是JVM内部创建的,我们无法使用
        //((Demo10AbstractNiMing$5) a).catchMouse();
    }
}

第四章 引用类型的传递【重点】

4.1 类作为方法的参数 11

//Student类
public class Student {
    private String name;
    private int age;
    //生成空参/满参,set和get方法
}
/*
    类作为方法的参数:
        调用方法时,传递的是对象的内存地址值
    注意:
        普通的类的数据的体现形式是对象
        抽象符类的数据的体现形式是子类对象
        接口的数据的体现形式是实现类对象
 */
public class Demo11ClassParam {
    public static void main(String[] args) {
        //创建Student类的对象
        Student stu = new Student("张三", 18);//地址值: 0x666
        //调用方法,传递Student类的对象
        //调用方法: show(0x666)
        show(stu);
    }

    //定义方法使用Student类作为参数
    //调用方法时,需要传递Student类型的数据
    //方法被调用时: Student stu = 0x666 = new Student("张三", 18)
    public static void show(Student stu) {
        System.out.println(stu.getName() + "::" + stu.getAge());
    }
}

类作为方法的参数的图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IeVEjzIF-1643037451880)(img/1600762962832.png)]

4.2 类作为方法的返回值 11

public class Demo11ClassParamReturn {
    public static void main(String[] args) {
        //调用方法获取Student类的对象
        //方法调用结束后: Student stu = 0x666 = new Student("张三", 18)
        Student stu = getStudent();//地址值: 0x666
        //调用方法,传递Student类的对象
        //调用方法: show(0x666)
        show(stu);
    }

    //定义方法使用Student类作为返回值类型
    //调用方法时,方法内部需要返回Student类型的数据
    public static Student getStudent() {
        Student stu = new Student("张三", 18);//地址值: 0x666
        return stu;//return 0x666
    }
    //定义方法使用Student类作为参数
    //调用方法时,需要传递Student类型的数据
    //方法被调用时: Student stu = 0x666 = new Student("张三", 18)
    public static void show(Student stu) {
        System.out.println(stu.getName() + "::" + stu.getAge());
    }
}

类作为方法的返回值图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mdl3Aqq8-1643037451881)(img/1600764478447.png)]

4.3 抽象类作为方法的参数 12

/*
    抽象类作为方法的参数
        调用方法时,必须传递抽象类的子类对象,本质传递的是对象的地址值

    注意:
        普通的类的数据的体现形式是对象
        抽象符类的数据的体现形式是子类对象
        接口的数据的体现形式是实现类对象
 */
public class Demo12AbstractParam {
    public static void main(String[] args) {
        //创建抽象类Animal的子类Dog类的对象
        Animal a = new Dog();//地址值: 0x666

        //调用方法传递抽象类Animal的子类Dog类的对象
        //调用方法: show(0x666)
        show(a);
    }

    //定义方法使用抽象类Animal作为参数
    //调用方法时必须传递抽象类Animal类型的数据
    //因为Animal是抽象类,必须传递子类对象
    //方法被调用时: Animal a = 0x666 = new Dog()   左边是父类类型,右侧是子类对象    多态
    public static void show(Animal a) {
        a.eat();
        a.sleep();
    }
}
public abstract class Animal {
    //抽象方法
    public abstract void eat();
    public abstract void sleep();
}
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("小狗吃骨头....");
    }

    @Override
    public void sleep() {
        System.out.println("小狗睡觉....");
    }
}

4.4 抽象类作为方法的返回值 12

public class Demo13AbstractParamReturn {
    public static void main(String[] args) {
        //调用方法获取抽象类Animal的子类对象
        //方法调用后: Animal a = 0x666 = new Dog() 左边是父类类型,右侧是子类对象    多态
        Animal a = getAnimal();//地址值: 0x666
        //调用方法传递抽象类Animal的子类Dog类的对象
        //调用方法: show(0x666)
        show(a);
    }
    //定义方法使用抽象类Animal作为返回值类型
    //调用方法时,方法内部必须返回Animal类型的数据
    //但是因为Animal是抽象类,必须返回抽象类的子类对象
    public static Animal getAnimal() {
        //创建抽象类Animal的子类Dog类的对象
        Animal a = new Dog();//地址值: 0x666
        return a;//return 0x666
    }
    //定义方法使用抽象类Animal作为参数
    //调用方法时必须传递抽象类Animal类型的数据
    //因为Animal是抽象类,必须传递子类对象
    //方法被调用时: Animal a = 0x666 = new Dog()   左边是父类类型,右侧是子类对象    多态
    public static void show(Animal a) {
        a.eat();
        a.sleep();
    }
}

4.5 接口作为方法的参数 13

/*
    接口作为方法的参数
	    调用接口时,必须传递接口的实现类对象,本质传递的是对象的内存地址值
 */
public class Demo13InterParam {
    public static void main(String[] args) {
        //创建SmokeAble接口的实现类对象
        SmokeAble smokeAble = new SmokeAbleTeacher();//地址值: 0x666

        //调用方法传递SmokeAble接口的实现类对象
        //调用方法时: show(0x666)
        show(smokeAble);
    }

    //定义方法,使用SmokeAble接口作为参数
    //调用方法时必须传递SmokeAble接口类型的数据
    //但是SmokeAble是接口,必须传递接口的实现类对象
    //方法被调用时: SmokeAble smokeAble = 0x666 = new SmokeAbleTeacher() 左侧是接口类型变量,右侧是实现类对象 多态
    public static void show(SmokeAble smokeAble) {
        smokeAble.somking();
    }
}
public interface SmokeAble {
    void somking();//抽象方法: 抽烟
}
public class SmokeAbleTeacher implements SmokeAble {
    @Override
    public void somking() {
        System.out.println("老师课后一支烟,课上活神仙....");
    }
}

4.6 接口作为方法的返回值 13

/*
    接口作为方法的返回值类型
	    调用接口时,方法内部必须返回接口的实现类对象,本质返回的是对象的内存地址值
 */
public class Demo14InterParamReturn {
    public static void main(String[] args) {
        //调用方法获取SmokeAble接口的实现类对象
        //方法被调用后: SmokeAble smokeAble = 0x666 = new SmokeAbleTeacher()  左侧是接口类型变量,右侧是实现类对象 多态
        SmokeAble smokeAble = getSmokeAble();//地址值: 0x666

        //调用方法传递SmokeAble接口的实现类对象
        //调用方法时: show(0x666)
        show(smokeAble);
    }

    //定义方法,使用SmokeAble接口作为返回值类型
    //调用方法时,方法内部必须返回SmokeAble接口类型的数据
    //但是SmokeAble是接口,必须返回接口实现类对象
    public static SmokeAble getSmokeAble() {
        //创建SmokeAble接口的实现类对象
        SmokeAble smokeAble = new SmokeAbleTeacher();//地址值: 0x666
        return smokeAble;//return 0x666
    }

    //定义方法,使用SmokeAble接口作为参数
    //调用方法时必须传递SmokeAble接口类型的数据
    //但是SmokeAble是接口,必须传递接口的实现类对象
    //方法被调用时: SmokeAble smokeAble = 0x666 = new SmokeAbleTeacher() 左侧是接口类型变量,右侧是实现类对象 多态
    public static void show(SmokeAble smokeAble) {
        smokeAble.somking();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值