一.内部类
1.1 什么是内部类
1.2 内部类分类
内部类4种形态
成员内部类 静态内部类 方法内部类( 局部内部类 ) 匿名内部类
二.成员内部类
2.1 理解
成员内部类,和实例属性 实例方法 动态代码块 构造器 是同一级别的事物,实例级别内容。
2.2 定义
//外部类
public class Foo {
//内部类:成员内部类
class Boo{
}
}
2.3 成员内部类成分
//外部类
public class Foo {
//内部类:成员内部类
class Boo{
int age; // OK 实例属性
static int name; //ERROR 不能定义静态属性
// OK 普通代码块
{
}
// ERROR 不可以定义
static {
}
//OK 构造器
public Boo(){
}
//OK 实例方法
public void m1(){
}
// ERROR 报错不可定义静态方法
public static void m2(){
}
}
}
2.4 成员访问规则
2.4.1 内部类访问外部
可以访问 实例信息和静态信息(全部),如果内部类访问外部类的同名属性默认,就近原则,通过 外部类名.this.xxx 可以强制区分外部类属性。
//外部类
public class Foo {
int fmoney;
static int fheight;
public void f1(){
}
public static void f2(){
}
//内部类:成员内部类
class Boo{
int age; //实例属性
public void m1(){ //实例方法
System.out.println( fmoney ); //OK 可直接访问
System.out.println( fheight); //OK 可直接访问
f1(); //OK 可直接访问
f2(); //OK 可直接访问
}
}
}
2.4.2 外部类访问内部
//外部类
public class Foo {
int fmoney;
static int fheight;
public void f1(){
Boo boo = new Boo(); // 1 创建对象
boo.m1(); // 2 对象来访问即可
}
public static void f2(){
}
//内部类:成员内部类
class Boo{
int age; //实例属性
public void m1(){ //实例方法
}
}
}
2.4.3 其他位置访问内部类
需要创建对象然后使用
public static void main(String[] args) {
//分开来写
Foo foo = new Foo();
Foo.Boo boo1= foo.new Boo();
//一步到位
Foo.Boo boo2 = new Foo().new Boo();
boo2.xx();
}
通过对象引用调用属性和方法。
内部类单独使用,声明类型的时候需要带外部类名一起声明。比如 Foo.Boo
2.5 成员内部类使用案例
/
package case2;
public class Car {
//名字
String brand;
public Car(String brand){
this.brand=brand;
}
//汽车行驶方法 需要发动机提供动力
public void run(){
System.out.println(brand+"启动");
Engine engine = new Engine();
engine.zhuan();
}
//引擎,对外不公开,专门为外部类设计,为外部类提供服务
private class Engine {
public void zhuan(){
System.out.println("发动机运行");
}
}
}
package case2;
// 内部类使用案例
public class TestCar {
public static void main(String[] args) {
Car car = new Car("宝马");
car.run();
}
}
三.静态内部类
3.1 理解
静态内部类,和静态属性 静态方法 静态代码块 是同一级别的事物,是类级别内容。
3.2 定义
public class Foo {
//静态内部类
static class Boo{
}
}
3.3 定义成分
public class Foo {
static class Boo{
int age ; // 实例属性 OK
static int money; // 静态方法 OK
// 构造器 OK
public Boo(){
}
// 实例方法 OK
public void m1(){}
// 静态方法 OK
public static void m2(){}
// 普通代码块OK
{
}
// 静态代码块 OK
static {
}
}
}
3.4 成员访问规则
3.4.1 内部类访问外部类
3.4.2 外部类访问内部类
就是一个普通类的访问方式:
通过类名访问静态属性和方法
通过对象访问实例属性和方法
3.4.3其他位置访问内部类
就是一个普通类的访问方式:
通过类名访问静态属性和方法
通过对象访问实例属性和方法
四.方法内部类
4.1 理解
4.2 定义
public class Foo {
public void f1(){
int age = 10;
//方法内部类
class Boo{
}
}
}
4.3 定义成分
public void f1(){
int age = 10;
// 内部类
class Boo{
//实例属性 OK
int age;
// 构造器 OK
public Boo(){
}
// 动态代码块 OK
{
}
public void m1(){ // 实例方法 OK
}
}
}
只能定义实例相关信息,不可定义静态内容,且不可添加访问权限。
4.4 成员访问规则
4.4.1 内部类访问外部类
4.4.2 外部类访问内部类
就是一个普通类的访问方式:
通过对象访问实例属性和方法 ,只能在内部类所在方法中使用
4.4.3 细节面试题
局部内部类访问 所在方法的 局部变量,要求这个变量是final修饰的,在JDK7必须强制声明为final,JDK8中无需声明,但是编译器依然要求它是一个final。
为什么呢? 需要延长局部变量的生命周期,保证对象使用该变量时,它是存在的,通过final 修饰的变量进入常量池,会一直保存。
五.匿名内部类
5.1 理解
没有名字的内部类,是一种特殊的局部内部类。它是把类的定义和对象创建合二为一。匿名内部类只能创建一次对象。匿名内部类必须是某个接口的实现类或者是某个类的子类。
5.2 定义
//接口
public interface CanFly {
public void fly();
}
public static void main(String[] args) {
CanFly xx = new CanFly(){
@Override
public void fly() {
System.out.println("小鸟飞");
}
};
}
5.3 编程中的运用
//创建面板时添加一个按钮
public Scene(){
//不要使用布局管理器,用坐标布局
this.setLayout(null);
JButton btn = new JButton("点我呀"); //创建一各按钮对象
btn.setBounds(0,0,100,30);//设置按钮位置
this.add(btn); //添加到面板
//添加一个点击监听
btn.addActionListener(new ActionListener() { //这里使用匿名内部类
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("你好呀");
}
});
}
GUI 编程, 体会面向对象编程
GUI 编程它是 图形化界面编程,目前的编程是控制台程序。
GUI java 的图形化编程是否流行 ?不流行,现在学习java 一般不学,但是可以做一些了解。它就是JAVA官方基于面向对象构建的一套编程技术。我们可以通过他们消化和理解面向对象的编程技术。
package case4.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
//程序入口
public class App {
public static void main(String[] args) {
//创建一个窗体对象
JFrame win = new JFrame();
//设置 标题
win.setTitle("千锋App");
//设置 尺寸
win.setSize(1000,600);
//添加一个面板
//JPanel pan = new JPanel();
//设置面板的颜色
//pan.setBackground( Color.ORANGE ); // java 万物皆为对象 颜色也是对象 Color类表示颜色类
JPanel pan = new JPanelPlus();
win.add( pan );
//设置 可见性
win.setVisible( true );
//设置 关闭操作
win.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
//事件处理 MouseAdapter 的匿名内部类
win.addMouseListener(
new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("helllo:"+e.getX()+"---"+e.getY());
}
}
);
// 键盘事件
win.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) { // KeyEvent e事件对象 保存事件信息
switch (e.getKeyCode()){
case KeyEvent.VK_W:
System.out.println("上");break;
case KeyEvent.VK_S:
System.out.println("下");break;
case KeyEvent.VK_A:
System.out.println("左");break;
case KeyEvent.VK_D:
System.out.println("右");break;
default:
System.out.println("输入错误");
}
}
});
}
}
package case4.gui;
import javax.swing.*;
import java.awt.*;
//自定义面板
public class JPanelPlus extends JPanel {
//JPpanel 不画任何东西,我们需要画东西,不得已来重写一盘。
@Override
public void paint(Graphics g) {
super.paint(g);
//画东西需要画笔 Graphics g 功能少
Graphics2D g2D = (Graphics2D) g;
g2D.setStroke( new BasicStroke(15) ); //设置画笔大小
//设置抗锯齿
g2D.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON );
g.setColor(Color.blue);
g.drawOval(220,220,200,200);
g.setColor(Color.darkGray);
g.drawOval(440,220,200,200);
g.setColor( Color.pink );
g.drawOval(100,100,200,200);
g.setColor(Color.orange);
g.drawOval(320,100,200,200);
g.setColor(Color.green);
g.drawOval(540,100,200,200);
}
}