目录
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类型,只能接收对象类型的数据,所以不能支持基本数据类型(万物皆对象)