目录
9.对象的打印
class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public void print(){
System.out.println("name:"+name+" gender:"+gender+" age:"+age);
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
person.print();
}
}
结果为
如果想要默认打印对象中内如该如何处理呢?答案:重写toString方法即可。
class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public void print(){
System.out.println("name:"+name+" gender:"+gender+" age:"+age);
}
//点击右键,选择Generate,选择toString(),选择OK
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
// person.print();
System.out.println(person);
}
}
运行结果为
10.内部类
先来看下,内部类都可以在一个类的那些位置进行定义
public class OutClass {
// 成员位置定义:未被static修饰 ---> 普通内部类
public class InnerClass1{
}
// 成员位置定义:被static修饰 ---> 静态内部类
static class InnerClass2{
}
public void method(){
// 方法中也可以定义内部类 ---> 局部内部类:几乎不用
class InnerClass5{
}
}
}
10.1成员内部类
在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。
10.1.1普通内部类
//调用实例内部类的实例化对象
class OuterClass{
public int data1=1;
private int data2=2;
public static int data3=3;
//实例内部类----与类里面的成员变量在同一级
class InnerClass{
public int dat4=4;
private int data5=5;
public void test(){
System.out.println("InnerClass的test()方法");
}
}
public void test2(){
System.out.println("OuterClass的test()方法");
}
}
public class TestDemo3 {
public static void main(String[] args) {
//1.如何调用实例内部类的对象----》类比调用类的实例化成员
OuterClass outerClass=new OuterClass();
//System.out.println(outerClass.data1);
OuterClass.InnerClass innerClass=outerClass.new InnerClass();
innerClass.test();
}
}
结果为
调用如何调用实例内部类的对象,有两种方法,如下图:
问题1:考虑一下,能否在实例内部类中定义静态呢?
根据上图,发现定义静态的时候标红了,那说明是不能直接定义静态的
我们可以通过final来将静态成员变量直接定义成常量来在实例内部类中定义静态。
问题2:在实例内部类重新定义data1时,结果是优先使用外部类的数据还是使用内部类的数据呢?
如上图,在实例内部类重新定义data1时,发现结果是优先使用内部类的
问题3:如何在内部类中调用外部类的成员变量??
如上图,表明实例内部类的方法可以通过 外部类名.this.成员变量 来调用,在调用内部类时最好也用上this.成员变量来进行区分。
总结:实例内部类中包含自己的this,也包含外部类的this
整体代码
class OuterClass{
public int data1=1;
private int data2=2;
public static int data3=3;
//实例内部类----与类里面的成员变量在同一级
class InnerClass{
public int data1=1111;
public int data4=4;
private int data5=5;
// public static int data6=6;//报错了,不能定义静态???
public static final int data6=6;//用final将data6变成一个常量,不再被修改值
public void test(){
System.out.println(OuterClass.this.data1);//调用外部类的成员变量
System.out.println(this.data1);//调用内部类
System.out.println(data2);
System.out.println(data3);
System.out.println(data4);
System.out.println(data5);
System.out.println(data6);
System.out.println("InnerClass的test()方法");
}
}
public void test2(){
System.out.println("OuterClass的test()方法");
}
}
public class TestDemo3 {
public static void main(String[] args) {
//1.如何调用实例内部类的对象----》类比调用类的实例化成员
OuterClass outerClass=new OuterClass();
//System.out.println(outerClass.data1);
OuterClass.InnerClass innerClass=outerClass.new InnerClass();
innerClass.test();
OuterClass.InnerClass innerClass1=new OuterClass().new InnerClass();
innerClass1.test();
}
}
总结:
实例内部类:
1、如何拿到实例内部类的一个对象呢?
OuterClass.InnerClass innerClass=outerClass.new InnerClass();
外部类名.内部类 变量=外部类对象的引用.新内部类对象()
2、实例内部类当中,定义的成员变量不能是静态的,如果定义只能是static final
3、在实例内部类当中如何访问和外部类同名的成员变量??
System.out.println(OuterClass.this.data1);//调用外部类的成员变量 System.out.println(this.data1);//调用内部类
结论:实例内部类当中包含外部类的this,也包含自己的this
4、实例内部类对应的字节码文件:外部类$内部类.class
[注意事项]
1.外部类中的任何成员都可以被在普通内部类方法中直接访问
2.普通内部类所处的成员与外部类成员位置相同,因此也受public,private等访问限定符的约束
3.在内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员来访问
4.普通内部类对象必须在先有外部类对象前提下才能创建
5.普通内部类的非静态方法中包含了一个指向外部类对象的引用
6.外部类中,不能直接访问内部类中的成员,如果要访问必须先要创建外部类的对象.
10.1.2静态内部类
1、如何拿到静态内部类对象?
OuterClass2.InnerClassu2 innerClassu2=new OuterClass2.InnerClassu2();
整体代码为:
class OuterClass2{
public int data1=1;
private int data2=2;
public static int data3=3;
static class InnerClassu2{
public int data1=1111;
public int data4=4;
private int data5=5;
public static final int data6=6;//用final将data6变成一个常量,不再被修改值
public void test(){
System.out.println("InnerClass2::test()");
}
}
}
public class TestDemo4 {
//如何拿到静态内部类对象
public static void main(String[] args) {
OuterClass2.InnerClassu2 innerClassu2=new OuterClass2.InnerClassu2();
innerClassu2.test();//拿到静态内部类对象
}
}
2、在静态内部类当中调用外部类的非静态成员时,发现如下图所示报错了
那么如何在静态内部类当中,获取外部类的非静态成员?
是不可以的!!!但是可以做到~
只要提供了外部类对象的引用就可以访问,所以问题就转变为,如何在静态内部类当中获取外部类的对象了?
如下图,可以new一个新的外部类对象,进行this.引用就可以了
class OuterClass2{
public int data1=1;
private int data2=2;
public static int data3=3;
static class InnerClassu2{
public int data1=1111;
public int data4=4;
private int data5=5;
public static final int data6=6;//用final将data6变成一个常量,不再被修改值
/* //方案2
public OuterClass2 out=new OuterClass2();*/
public OuterClass2 out;//方案3
//方案2~~~
public InnerClassu2(OuterClass2 out){
this.out=out;
}
//方案4
public InnerClassu2(){
}
public void test(){
System.out.println(this.data1);//调用内部类
//System.out.println(data2);//报错了,那么如何调用外部类的非静态成员???
//方案1
OuterClass2 outerClass2=new OuterClass2();
System.out.println(outerClass2.data2);//方案 1
System.out.println(out.data2);//方案2
System.out.println(data3);
System.out.println(data4);
System.out.println(data5);
System.out.println(data6);
System.out.println("InnerClass2::test()");
}
}
}
public class TestDemo4 {
public static void main(String[] args) {
//方案2
OuterClass2 out=new OuterClass2();
OuterClass2.InnerClassu2 innerClassu2=new OuterClass2.InnerClassu2(out );
}
//如何拿到静态内部类对象
public static void main1(String[] args) {
OuterClass2.InnerClassu2 innerClassu2=new OuterClass2.InnerClassu2();
innerClassu2.test();//拿到静态内部类对象
}
}
【 注意事项 】1. 在内部类中只能访问外部类中的静态成员2. 创建内部类对象时,不需要先创建外部类对象3. 成员内部类,经过编译之后会生成独立的字节码文件,命名格式为:外部类名称 $ 内部类名称
10.1.3局部内部类
public class OutClass {
int a = 10;
public void method(){
int b = 10;
// 局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰
class InnerClass{
public void methodInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
// 只能在该方法体内部使用,其他位置都不能用
InnerClass innerClass = new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
// OutClass.InnerClass innerClass = null; 编译失败
}
}
【 注意事项 】1. 局部内部类只能在所定义的方法体内部使用2. 不能被 public 、 static 等修饰符修饰3. 编译器也有自己独立的字节码文件,命名格式:外部类名字 $x 内部类名字 .class , x 是一个整数。4. 几乎不会使用