1.权限修饰符
public:访问权限是最大的,任何地方都可以访问
private:访问权限是最小的,只能在本类中访问
protected:只能子类中访问
默认:只能在同一个包中访问
2.内部类
概述:就是在类的内部定义一个类,内部类可以看成外部类的成员,内部类具有类的特性
内部类可以直接访问外部类的成员,包括私有成员;外部类想要访问内部类的成员,需要创建对象
分类:
成员内部类:定义在成员位置上
成员内部类可以被static修饰,为了成员访问方便
访问成员内部类的方式:
访问非静态内部类的非静态成员:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
对象名.成员;
访问静态成员内部类的非静态成员:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
对象名.成员;
访问静态成员内部类的静态成员:
外部类名.内部类名.成员;
成员内部类的特点:静态成员内部类中不一定有静态成员,有静态成员的内部类一定是静态内部类
成员内部类可以被private修饰,为了安全性:一个人的身体可以看成一个对象,可以用一个类来表示,同时一个人的身体又有很多
个器官,每一个器官也可以用一个类表示;有的器官,比如眼睛,头发都可以定义成公共的;有的器官,比如:心脏,大脑是
需要保护起来,所以可以定义成私有的。
局部内部类:定义在局部位置上
局部内部类使用局部变量的时候,这个局部变量必须是常量;JDK1.8之后不需要明确的加final。
为什么局部内部类访问局部变量必须是final类型的呢?
因为局部变量在方法执行结束之后就从内存中消失了,如果在类中还可以被赋值就不符合逻辑,所以必须定义成常量
3.匿名内部类
概述:其实就是内部类的简化写法,就是没有名字的一个内部类子类对象
前提:必须有一个类或者接口
格式:
new 类名或接口名(){
重写或者实现的方法;
}
public:访问权限是最大的,任何地方都可以访问
private:访问权限是最小的,只能在本类中访问
protected:只能子类中访问
默认:只能在同一个包中访问
2.内部类
概述:就是在类的内部定义一个类,内部类可以看成外部类的成员,内部类具有类的特性
内部类可以直接访问外部类的成员,包括私有成员;外部类想要访问内部类的成员,需要创建对象
分类:
成员内部类:定义在成员位置上
成员内部类可以被static修饰,为了成员访问方便
访问成员内部类的方式:
访问非静态内部类的非静态成员:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
对象名.成员;
访问静态成员内部类的非静态成员:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
对象名.成员;
访问静态成员内部类的静态成员:
外部类名.内部类名.成员;
成员内部类的特点:静态成员内部类中不一定有静态成员,有静态成员的内部类一定是静态内部类
成员内部类可以被private修饰,为了安全性:一个人的身体可以看成一个对象,可以用一个类来表示,同时一个人的身体又有很多
个器官,每一个器官也可以用一个类表示;有的器官,比如眼睛,头发都可以定义成公共的;有的器官,比如:心脏,大脑是
需要保护起来,所以可以定义成私有的。
局部内部类:定义在局部位置上
局部内部类使用局部变量的时候,这个局部变量必须是常量;JDK1.8之后不需要明确的加final。
为什么局部内部类访问局部变量必须是final类型的呢?
因为局部变量在方法执行结束之后就从内存中消失了,如果在类中还可以被赋值就不符合逻辑,所以必须定义成常量
3.匿名内部类
概述:其实就是内部类的简化写法,就是没有名字的一个内部类子类对象
前提:必须有一个类或者接口
格式:
new 类名或接口名(){
重写或者实现的方法;
}
本质:其实就是继承了一个类或者实现一个接口的匿名子类对象
public class NoNameInnerClassDemo{
public static void main(String[] args){
//传统写法
new Dog().say();
//匿名内部类写法
new Animal(){
public void say(){
System.out.println("匿名内部类方式方式重写类的方法");
}
}.say();
//传统写法
new Son().test();
//匿名内部类写法
new Father(){
public void test(){
System.out.println("匿名内部类方式实现抽象类抽象方法");
}
}.test();
//传统方式
new InterImpl().show();
//匿名内部类写法
new Inter(){
public void show(){
System.out.println("匿名内部类方式实现接口的抽象方法");
}
}.show();
}
}
//接口
interface Inter{
void show();
}
class InterImpl implements Inter{
public void show(){
System.out.println("传统方式实现接口的抽象方法");
}
}
//抽象类
abstract class Father{
public abstract void test();
}
class Son extends Father{
public void test(){
System.out.println("传统实现抽象类抽象方法");
}
}
//普通类
class Animal{
public void say(){
System.out.println("动物都会叫");
}
}
class Dog extends Animal{
public void say(){
System.out.println("传统方式重写类的方法");
}
}
/*
使用匿名内部类调用多个方法:使用一个当前接口或者类的引用变量来接收匿名内部类对象
*/
public class NoNameInnerClassDemo2{
public static void main(String[] args){
//本质上是创建了一个InterTest的匿名子类对象
//所以可以使用当前接口的引用变量来接收
InterTest it = new InterTest(){
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
public void show3(){
System.out.println("show3");
}
public void show4(){
System.out.println("show4");
}
};
it.show();
it.show2();
it.show3();
it.show4();
}
}
interface InterTest{
void show();
void show2();
void show3();
void show4();
}
/*
在开发中当一个方法的参数是一个接口或者抽象类的时候,可以直接使用匿名内部类创建对象当做参数传递给方法
*/
public class NoNameInnerClassDemo3{
public static void main(String[] args){
//如何调用show方法?
//传统方式:新定义一个子类实现接口,然后创建子类的对象
show(new InterTeset2Impl());
//匿名内部类方式:直接使用匿名内部类实现所有的方法,然后匿名内部类对象直接传递给方法当做参数
show(new InterTest2(){
public void show(){
System.out.println("匿名内部类方式show");
}
public void show2(){
System.out.println("匿名内部类方式show2");
}
public void show3(){
System.out.println("匿名内部类方式show3");
}
public void show4(){
System.out.println("匿名内部类方式show4");
}
});
}
public static void show(InterTest2 it){
it.show();
it.show2();
it.show3();
it.show4();
}
}
interface InterTest2{
void show();
void show2();
void show3();
void show4();
}
class InterTeset2Impl implements InterTest2{
public void show(){
System.out.println("传统方式show");
}
public void show2(){
System.out.println("传统方式show2");
}
public void show3(){
System.out.println("传统方式show3");
}
public void show4(){
System.out.println("传统方式show4");
}
}
/*
内部类:就是定义在类的内部的一个类,内部类也可以看成外部类的成员,内部类有类的全部特点
内部类分类:
成员内部类:定义在成员位置上
局部内部类:定义在局部位置上
*/
class InnerClassDemo{
//成员内部类:定义在成员位置上
class A{}
public void show(){
//局部内部类:定义在局部位置上
class B{}
}
}
面试题1
abstract class Demo{
public abstract void show();
}
interface Inter{
Demo test();
}
class InnerClass{
//补齐代码
public static Inter show(){
//返回Inter的子类对象
return new Inter(){
public Demo test(){
//返回Demo的子类对象
return new Demo(){
public void show(){
System.out.println("HelloWorld");
}
};
}
};
}
}
class NoNameInnerClassTest {
public static void main(String[] args) {
//1.InnerClass是一个类,通过类名直接调用的show方法肯定是静态的
//2.调用完show方法之后,show方法的返回值可以调用test方法,test方法是Inter接口的抽象方法,
//所以show方法的返回值类型是Inter,show方法的返回值就是Inter的子类对象
//3.test方法的返回值又可以调用show方法,show方法是Demo抽象类的抽象方法,所以test方法的返回值是Demo的子类对象
InnerClass.show().test().show();
//使用InnerClass类名调用show方法
//使用show方法的返回值调用test方法
//使用test方法的方法值调用show方法
}
}
//要求在控制台输出”HelloWorld”
面试题2
/*
要求请填空分别输出不同age的值30,20,10。
注意:
1.内部类和外部类没有继承关系。
2.通过外部类名限定this对象:OuterClass.this
*/
class OuterClass{
int age = 10;
class InnerClass{
int age = 20;
public void show(){
int age = 30;
//分别输出30,20,10
System.out.println(age);//30
System.out.println(this.age);//20
System.out.println(OuterClass.this.age);
}
}
}
public class InnerClassTest{
public static void main(String[] args){
new OuterClass().new InnerClass().show();
}
}
/*
局部内部类:就是定义在局部位置上
局部内部类可以直接访问外部类的成员
外部类想要访问局部内部类的成员:在所在的方法中创建该类的对象,然后调用该对象的方法
局部内部类访问局部变量为什么要定义成常量呢?
局部变量是在方法结束之后就从内存中消失了,但是我们局部内部类还在使用,如果不加final,
那么这个变量都消失了还可以被改变值,从逻辑上是说不通的
*/
public class InnerClassDemo4{
public static void main(String[] args){
new OuterClass2().show();
}
}
class OuterClass2{
private String name = "隔壁老王";
public void show(){
//JDK1.8之后局部内部类访问局部变量不需要显示的加final了
final int age = 10;
//局部内部类:就是定义在局部位置上
class InnerClass2{
public void show(){
//错误: 从内部类引用的本地变量必须是最终变量或实际上的最终变量
//age = 20;
System.out.println(age);
name = "隔壁老张";
System.out.println(name);
}
}
new InnerClass2().show();
}
}