内部类定义:
在一个类的里面,再定义一个类。
eg:Inter被称为内部类。
public class Outer{
public class Inner{
}
}
内部类应用场景:
需求:写一个javabean类表述汽车。
属性:汽车品牌,年龄,发动机的品牌,使用年限
public class car{
String carName;
int carAge;
int carColor;
class Engine{
String engineName;
int engineAge;
}
}
内部类表示的事物是外部类的一部分
内部类单独出现没有任何意义
内部类的访问特点:
内部类可以直接访问外部类的成员,包括私有。
外部类访问内部类的成员,必须创建对象。
public class car {
String name;
String color;
public void show(){
engine e=new engine();
System.out.println(e.engineName);
}
class engine{
String engineName;
public void show(){
System.out.println(engineName);
System.out.println(name);
}
}
内部类的分类:
成员内部类,静态内部类,局部内部类,匿名内部类(掌握)
成员内部类:
写在成员位置的,属于外部类的成员
如上代码中的car为外部类,engine为成员内部类
书写成员内部类的代码
成员内部类可以被一些修饰符修饰,如:private,public,static(可以修饰成员变量的也可以修饰成员内部类)。
成员内部类一旦被private修饰,则只能在本类使用。
不写修饰符,则为默认,只能在本包中使用。
用protected修饰,可以在其他包的子类使用。
创建和获取成员内部类的对象:
1.在外部类中编写方法,对外提供内部类的对象(用private修饰内部类时,常用此方式)
public class Outer {
class Inter{
}
public Inter getInstance() {
return new Inter();
}
}
///
public class Test {
public static void main(String[]args) {
Outer o=new Outer();
Object a=o.getInstance();
//用变量接收,因为Inter没有父类默认继承Object
System.out.println(o.getInstance());
}
}
2.直接创建格式:外部类名.内部类名 对象名=外部类对象.内部类对象;
public class Outer {
class Inter{
//若内部类被private修饰,则创建其对象会报错
}
}
//
public class Test {
public static void main(String[]args){
Outer.Inter oi=new Outer().new Inter();
}
}
成员内部类获取外部类的成员变量
public class Outer {
private int a=10;
class Inter{
private int a=20;
public void show(){
int a=30;
System.out.println(a);//30
System.out.println(this.a);//20
System.out.println(Outer.this.a);//10
//Outer.this获取外部类对象的地址值。
}
}
}
静态内部类和局部内部类
静态内部类:
只能访问外部类中的静态变量和静态方法,如果要访问非静态的需要创建对象。(类似于静态方法的访问形式)
创建静态内部对象的格式:外部类名.内部类名 对象名=new 外部类名.内部类名();
1.调用非静态方法的格式:先创建对象,用对象调用
2.调用静态方法的格式:外部类名.内部类名.方法名();
public class Main {
static class Inter{
public void show1(){
System.out.println("非静态方法被调用");
}
public static void show2(){
System.out.println("静态方法被调用");
}
}
}
/调用方法
public class work {
public static void main(String[] args) {
Main.Inter mi=new Main.Inter();
mi.show1();
//调用静态方法两种方式
mi.show2();
Main.Inter.show2();
}
}
局部内部类:
1.将内部类定义在方法里就叫做局部内部类,类似于方法里的局部变量
2.外界无法直接使用,需要在方法内部创建对象并使用
3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public class Outer {
public void show(){
//局部内部类(可以用来修饰局部变量的也可以修饰局部内部类,反之一样)
class Inter{
int a=10;
String name;
int age;
public void method1() {
System.out.println(a);
System.out.println("局部内部类中的method1方法");
}
public void method2() {
System.out.println("局部内部类中的method2方法");
}
}
Inter n=new Inter();
n.method1();
n.method2();
}
}
public class Test {
public static void main(String[]args){
Outer o=new Outer();
o.show();
}
}
匿名内部类:
隐藏了名字的内部类。(并不是没有名字,java自动命名:外部类类名$序号)
格式:
new 类名或接口名(){
重写方法;
};
内部类包含三部分:继承/实现(类/接口) ;方法重写; 创建对象;
public interface Swim{
public abstract void swim();
}
public class Test {
public static void main(String[] args){
new Swim(){//因为Swim是接口,所以是实现关系
@Override
public void swim(){
System.out.println("重写方法");
}
};
}
}
应用场景:
public class Animal {
public void eat(){
System.out.println();
}
}
public class Test {
public static void main(String[] args){
//这个整体是new出来的对象
new Animal(){//到后面大括号是一个没有名字的类;
@Override
public void eat(){
System.out.println("重写了eat方法");
}
};
method(
//将下面看作Animal的子类对象
new Animal(){
public void eat(){
System.out.println("狗吃骨头");
}
}//将此对象当作参数传递到下面方法参数中的Animal a
);
}
//在测试类中写一个方法,如何调用
public static void method(Animal a){//Animal a=子类对象
a.eat();//编译看左边,运行看右边
}
}
拓展:
public class Test {
public static void main(String[] args) {
//整体可以理解为Swim接口的实现类对象
//接口多态
Swim s= new Swim(){
@Override
public void swim() {
System.out.println("重写方法");
}
};
//调用方法,编译看左边,运行看右边
//第一种方法
s.swim();
//第二种方法(下面是一个对象,而且是new Swim后面没有名子的类创建出来的,所以可以调用方法)
new Swim(){
@Override
public void swim(){
System.out.println("重写方法");
}
}.swim();
}
}