JAVA基础-面向对象进阶(三)

目录

1.内部类

1.1 成员内部类

 1.2 静态内部类

 1.3 局部内部类

1.4 匿名内部类(重点)

 1.4.1 匿名内部类在开发中的使用场景

1.4.2 匿名内部类的拓展

 2.枚举

2.1 枚举的应用场景

3. 泛型

3.1 泛型类

3.2 泛型接口

 3.3 泛型方法

3.4 通配符和上下限


1.内部类

1.1 成员内部类

  • 就是类中的一个普通成员,类似前面我们学过的普通的成员变量、成员方法

public class Outer {

        //成员内部类

        public class Inner {

        }

}

package com.itheima.innerclass1;
//外部类
public class Outer {
    public static String schoolName = "清华";
    public static void inAddr(){
        System.out.println("我们在北京!");
    }
    private String hobby;
    private double height;
    public void run(){
        System.out.println("run");
    }
    //成员内部类
    //特点:无static修饰,属于外部类的对象持有的
    //必须存在外部类对象,才会有这个成员内部类
    public class Inner{
        private String name;
        private int age;

        public Inner() {
        }

        public Inner(String name, int age) {
            this.name = name;
            this.age = age;
        }
        //拓展:成员内部类访问外部类的成员特点。
        public void show(){
            //1.成员内部类中,可以直接访问外部类的静态成员
            System.out.println(schoolName);
            inAddr();

            //2.成员内部类中,可以直接访问外部类的实例成员
            System.out.println(hobby);
            System.out.println(height);
            run();
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
}
package com.itheima.innerclass1;

public class People {
    private int hearBeat = 110;
    //成员内部类
    public class Heart{
        private int heartBeat = 95;
        public void show(){
            int heartBeat = 80;
            System.out.println(heartBeat);//80
            System.out.println(this.heartBeat);//95
            //拿到当前外部类对象:外部类名.this.变量名
            System.out.println(People.this.hearBeat);//110
        }
    }
}
package com.itheima.innerclass1;

public class Test {
    public static void main(String[] args) {
        //目标:掌握成员内部类,搞清楚语法就可以了
        //成员内部类创建对象的语法
        //外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
        Outer.Inner in = new Outer().new Inner();
        in.setName("张三");
        in.show();

        People
    }
}

 1.2 静态内部类

package com.itheima.innerclass2;

public class Outer {
    public static String schoolName = "清华";
    public static void inAddr(){
        System.out.println("我们在北京!");
    }
    //创建属于外部类对象的实例成员
    private double height;
    //静态内部类:有static修饰,属于外部类本身的
    public static class Inner{
        //类有的成员他都有
        private String name;
        private int age;

        public Inner() {
        }

        public Inner(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public void show(){
            //1.静态内部类中,可以直接访问外部类的静态成员
            System.out.println(schoolName);
            //2.静态内部类中,不能直接访问外部类的实例成员
            //System.out.println(height);//报错
            Outer o = new Outer();
            System.out.println(o.height);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
}
package com.itheima.innerclass2;
//外部类
public class Test {
    public static void main(String[] args) {
        //目标:认识静态内部类,搞清楚其特点
        //外部类名.内部类 对象名 = new 外部类名.静态内部类();
        Outer.Inner in = new Outer.Inner();
        in.show();
    }


}

 1.3 局部内部类

1.4 匿名内部类(重点)

 

public class Test {
    public static void main(String[] args) {
        //目标:认识匿名内部类。
        //匿名内部类本质是一个子类,同时会立即创建一个子类对象
        //匿名内部类的名称:当前类名&编号
        Animal a = new Animal() {
            @Override
            public void cry() {
                System.out.println("狗汪汪汪的叫~~~");
            }
        };
        a.cry();

    }
}

//class Dog extends Animal{
//    @Override
//    public void cry() {
//        System.out.println("狗汪汪汪的叫~~~");
//    }
//}
//抽象类不允许创建对象
abstract class Animal{
    public abstract void cry();
}

 1.4.1 匿名内部类在开发中的使用场景

  • 通常作为一个参数传输给方法

public class Test2 {
    public static void main(String[] args) {
        //目标:匿名内部类的使用场景:通常作为一个对象参数传输给方法使用
        Swimming s1 = new Swimming() {
            @Override
            public void swim() {
                System.out.println("学生游泳贼快~~~");
            }
        };
        go(s1);

        go(new Swimming() {
            @Override
            public void swim() {
                System.out.println("老师贼慢~~~");
            }
        });
    }

    public static void go(Swimming s){
        System.out.println("开始。。。");
        s.swim();
        System.out.println("结束。。。");
    }
}


//需求:学生和老师要一起参加游泳比赛
interface Swimming{
    void swim();
}

1.4.2 匿名内部类的拓展

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Test3 {
    public static void main(String[] args) {
        //拓展:掌握匿名内部类的真实场景
        //GUI SWING编程:桌面编程
        //1.创建一个窗口
        JFrame win = new JFrame("登录一下");

        JPanel panel = new JPanel();
        win.add(panel);

        JButton btn = new JButton("登录");
        panel.add(btn);

        //给按钮绑定单击时间监听器对象,可以用来监听用户的点击,以便做出反应
        //监听器对象需要的参数是一个接口对象,但是接口不能有对象,所以可以用匿名内部类
        //也可以定义一个实现类来创建接口对象,但是很麻烦
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("点击我,我要登录了!");
                JOptionPane.showMessageDialog(win,"没事别点我!讨厌你!");
            }
        });

        //2.设计大小,居中提示
        win.setSize(400,300);
        win.setLocationRelativeTo(null);
        win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        win.setVisible(true);
    }
}

匿名内部类是作为一个对象参数传输给方法使用的,至于什么时候用匿名内部类要看实际开发的需要,遇到了才用,没有遇到不会主动用。

  • 还有一个很重要的作用:简化代码(新技术的基础)

 2.枚举

//枚举类
public enum A {
    //枚举类的第一行必须罗列的是枚举对象的名称
    X, Y, Z;
    //其他成员
    private String name;

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

 

public class Test {
    public static void main(String[] args) {
        //目标:认识枚举类。搞清楚枚举类的特点
        //A a = new A();//报错
        A a1 = A.X;
        A a2 = A.Y;
        System.out.println(a1);
        System.out.println(a2);

        System.out.println("------------------");
        //values方法拿到枚举类的全部对象,放到一个数组中去返回
        A[] as = A.values();
        for (int i = 0; i < as.length; i++) {
            A a = as[i];
            System.out.println(a);
        }

        A y = A.valueOf("Y");
        System.out.println(y == a2);

        //ordinal拿对象的索引!
        System.out.println(a1.ordinal());//0
        System.out.println(a2.ordinal());//1
    }
}

 

2.1 枚举的应用场景

  •  用来表示一组信息,然后作为参数进行传输

public class Constant {
    public static final int DOWN = 1;
    public static final int UP = 2;
    public static final int HALE_UP = 3;
    public static final int DELETE_LEFT = 4;
}
public class Test {
    public static void main(String[] args) {
        //目标:搞清楚枚举的应用场景:信息标志和信息分类
        //需求:需要你提供一个方法,可以完成向下取整,向上取整,四舍五入,去掉小数部分
        //常量做信息标准和分类,也很优雅,大那是参数值不被约束
        System.out.println(handleData(3.1,Constant.DOWN));
        System.out.println(handleData(5.99,Constant.HALE_UP));
    }

    public static double handleData(double number,int flag){
        switch (flag){
            case Constant.DOWN:
                //向下取整
                number = Math.floor(number);//3.9999 == 3
                break;
            case Constant.UP:
                //向上取整
                number = Math.ceil(number);//3.1 == 4
                break;
            case Constant.HALE_UP:
                //四舍五入
                number = Math.round(number);//3.6 == 4
                break;
            case Constant.DELETE_LEFT:
                //去掉小数部分
                number = (int)number;
                break;
        }
        return number;
    }
}

常量做信息标准和分类,也很优雅,但是handleData方法中的参数不被约束,可任意填写。

但是枚举做信息标准和分类,很优雅,参数值受到约束,最好的信息标志和分类的理想方案。 

3. 泛型

 

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
//        ArrayList list = new ArrayList<>();
//        list.add("java");
//        list.add("清华大学");
//        list.add(true);
//        list.add(false);
//        list.add(99.5);
//
//        //1.开发中很多时候需要统一数据类型(如果不使用泛型,类型没有办法统一,就需要进行强制转换!)
//        for (int i = 0; i < list.size(); i++) {
//            Object ele = list.get(i);
//            String result = (String)ele;//强制转换
//            System.out.println(result);
//        }

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

        //ArrayList<String> list2 = new ArrayList<String>();
        ArrayList<String> list2 = new ArrayList<>();//JDK1.7开始,后面的类型可以不写
        list2.add("java");
        list2.add("清华大学");
        list2.add("我是bbb");

        for (int i = 0; i < list2.size(); i++) {
            String ele = list2.get(i);
            System.out.println(ele);
        }

    }
}

3.1 泛型类

import java.util.ArrayList;

//泛型类
public class MyArrayList<E> {
    private ArrayList list = new ArrayList();
    public boolean add(E e){
        list.add(e);
        return true;
    }

    public boolean remove(E e){
        return list.remove(e);
    }

    @Override
    public String toString() {
        return list.toString();
    }
}
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        //目标:掌握泛型类的定义
        //需求:模拟ArrayList集合,自定义一个MyArrayList的泛型类
        MyArrayList<String> list = new MyArrayList();
        list.add("张无忌");
        list.add("赵敏");
        list.add("周芷若");
        //list.add(46);//报错
        list.remove("周芷若");
        System.out.println(list);
    }
}

这是一种装饰设计模式,把别人的对象包装起来

3.2 泛型接口

 

 目标:认识泛型接口的使用架构
需求:必须完成学生,老师数据的增删改查操作。

 3.3 泛型方法

import com.itheima.d9_genericity_interface.Student;

public class Test {
    public static void main(String[] args) {
        //目标:认识泛型方法。
        //需求:要求接受认识对象数组。
        String[] names = {"谢霆锋","陈羽凡","王宝强","贾乃亮"};
        printArrat(names);

        Student[] students = new Student[60];
        printArrat(students);
    }

    public static <T> T printArrat(T[] array){
        return array[0];
    }
}

3.4 通配符和上下限

 

import java.util.ArrayList;

public class Test2 {
    public static void main(String[] args) {
        //目标:通配符和上下限
        //需求:所有汽车要一起参与比赛
        ArrayList<TSL> tsls = new ArrayList<>();
        tsls.add(new TSL());
        tsls.add(new TSL());
        tsls.add(new TSL());
        go(tsls);

        ArrayList<LX> lxes = new ArrayList<>();
        lxes.add(new LX());
        lxes.add(new LX());
        lxes.add(new LX());
        go(lxes);

        //当没有规定泛型时,可以加入其他类型的数据
        ArrayList list = lxes;
        list.add("宝马");

        //泛型不能直接支持基本数据类型,只能支持对象类型(引用数据类型)
        //ArrayList<int> list = new ArrayList<>();//报错
    }

    //虽然LX和TSL是Car的子类,但是ArrayList<TSL>和ArrayList<LX>与ArrayList<Car>没有关系
    //通配符:其实就是?,可以在使用泛型时代表一切类型.E,T,K,V是定义时使用
    //泛型的上下限:? extends Car(上限,? 必须是Car或者Car的子类)
    //           ? super Car(下限,? 必须是Car或者Car的父类)
    public static void go(ArrayList<? extends Car> cars){

    }
}

class Car{
}
class BMW extends Car{
}
class TSL extends Car{
}
class LX extends Car{

}
class Dog{}

 

 泛型在编译时E T K V都会编程object类型,只能接收对象类型的数据,所以不能支持基本数据类型(万物皆对象)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值