详解Java内部类与对象的打印概念和流程
作者:Luka.lh 发布时间:2021-10-10 21:36:56
一、内部类的概念
在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
public class OutClass {//外部类
class InnerClass{//内部类
}
}
注意事项:
1、内部类一定是定义在class 类名{}之中的类,定义在class 类名{}之外的,哪怕是在一份文件中,也并不能称为内部类。例如:
public class A{
}
class B{
}
//A和B两个类是独立的,无内外部类一说
2、内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件。
二、内部类的分类
public class OutClass {
//普通内部类
class InnerClass1{
}
//静态内部类
static class InnerClass2{
}
{
//定义在实例代码块中的 局部内部类
class InnerClass3{
}
}
static{
//定义在静态代码块中的 局部内部类
class InnerClass4{
}
}
public void method(){
//定义在方法中的 局部内部类
class InnerClass5{
}
{
//方法中的普通代码块中也可以定义局部内部类
class InnerClass6{
}
}
}
}
根据内部类定义的位置不同,可以分为:
成员内部类:普通内部类和静态内部类。
局部内部类和匿名内部类。
三、成员内部类
1、普通内部类
未被static修饰的成员内部类。
public class OutClass {//外部类
private int a;
private int b;
private int c;
public void method1(){
a=100;
System.out.println(a);
}
public void method2(){
System.out.println(b);
}
class InnerClass{ //普通内部类
private int c; //与外部类成员变量名称相同的内部成员变量
public void methodInner() {
//在内部类中可以直接访问外部类任意限定符的成员变量和方法
b = 150;
method1();
method2();
//在访问与外部类成员名称相同的成员时,优先访问内部类自己的成员
c = 300;
System.out.println(c);
//要访问外部类中的同名成员必须使用——— 外部类名.this.成员名 来访问
OutClass.this.c = 400;
System.out.println(OutClass.this.c);
}
}
public static void main(String[] args) {
//创建内部类对象
OutClass.InnerClass innerclass1=new OutClass().new InnerClass();
//也可以先创建外部类对象,再创建内部类对象
OutClass outclass=new OutClass();
//注意当在不同文件中创建其内部类对象一定需要加上该内部类的外部类名,同一文件下可加可不加
OutClass.InnerClass innerclass2=outclass.new InnerClass();
innerclass2.methodInner();
}
}
/*
100
150
300
400
*/
注意事项:
1、普通内部类中可以直接访问外部类中的所有方法。
2、普通内部类成员的位置与外部类成员位置相同,都受public,private等限定符的限制。
3、在普通内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问。
4、要创建普通内部类对象,要先创建外部类的对象。在创建内部类对象时,如果该内部类在当前文件,则在创建对象语句最前面不需要外部类名,如果在不同文件,那么一定要指明该内部类的外部类名。
5、 普通内部类中包含了一个指向外部类对象的引用。
6、外部类中,不能直接访问内部类中的成员,如果要访问必须先要创建内部类的对象。
public class OutClass1 {
private int a;
public void method(){
System.out.println(c); //在外部类中直接访问内部类成员,编译报错
}
class InnerClass{
private int c;
}
}
public class OutClass1 {
private int a;
public void methodOut(){
InnerClass I2=new InnerClass();//在外部类方法中创建内部类对象可以直接创建
System.out.println(I2.c);
}
class InnerClass{
private int c;
}
}
从堆和栈的角度来看内部类和外部类:
2、静态内部类
被static修饰的成员内部类称为静态内部类。
public class OutClass {//外部类
private int a;
static int b; //静态变量
public void method1(){
}
public static void method2(){ //静态方法
}
static class InnerClass{ //静态内部类
public void methodInner() {
//在静态内部类中只能访问外部类的静态成员和方法
// a=100;编译失败,a不是外部类的成员变量
b = 150;
// method1();编译失败,method1不是外部类的成员方法
method2();
}
}
public static void main(String[] args) {
//静态内部类的创建
InnerClass innerclass=new InnerClass();
//成员访问
innerclass.methodInner();
}
}
注意事项:
1、在内部类中只能访问外部类中的静态成员。
2、创建静态内部类对象时,不需要先创建外部类对象。
3、成员内部类,经过编译之后会生成自己独立的字节码文件,例如下:
四、局部内部类
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用。
public class OutClass {//外部类
int a=10;
public void method(){ //外部类方法
int b=10;
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) {
//InnerClass innerclass=null; 编译失败
}
}
注意事项:
1、局部内部类只能在所定义的方法体内部使用。
2、局部内部类不能被public、static等限定符修饰。
3、同样编译之后局部内部类会生成自己的字节码文件。
命名格式:外部类名$x内部类名.class, 其中x是一个整数。
五、对象的打印
public 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 static void main(String[] args) {
Person person=new Person("luka","man",21);
System.out.println(person);
}
}
打印结果: 并不是对象本身。
如果想要打印对象本身,那么需要重写toString方法。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public String toString() { //重写了toString方法
return "[" + name + "," + gender + "," + age + "]";
}
public 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 String toString() { //重写了toString方法
return "[" + name + "," + gender + "," + age + "]";
}
public static void main(String[] args) {
Person person=new Person("luka","man",21);
System.out.println(person);
}
}
/*
执行结果:
[luka,man,21]
*/
来源:https://blog.csdn.net/m0_58715346/article/details/120498819


猜你喜欢
- 这篇文章主要介绍了Springboot创建子父工程过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- 创建AlertDialog的步骤:1、创建AlertDialog.Builder对象2、调用Builder对象的setTitle
- LZ77压缩算法原理的理解数据压缩是一个减小数据存储空间的过程,目前被应用在软件工程的各个地方,了解其一些原理,方便我们更好的甄选压缩方案。
- windows应用程序(包括控制台)在运行时如果出现了未处理的异常会出项windows的异常提示框 &nb
- 如下所示:package com.lcn.day05;import java.util.Scanner;public class Array
- 关于实现网易新闻客户端的界面,以前写过很多博客,请参考:Android实现网易新闻客户端效果Android实现网易新闻客户端侧滑菜单(一)A
- 查询返回Map<String,Object>类型mybatis 查询返回Map<String,Object> 类型,
- 一、题目描述题目实现:网络通信,实现信息的发送和接收。二、解题思路创建一个服务器类:ServerSocketFrame,继承JFrame类写
- HashMap 的线程不安全HashMap 的线程不安全主要体现在下面两个方面在 jdk 1.7 中,当并发执行扩容
- java可以通过Runtime.getRuntime().exec()执行一个操作系统的命令,在操作系统层面执行命令也就创建了一个进程,Ja
- 在主Activity中:listview=(ListView)findViewById(R.id.listview);getData();/
- 前言前面我们学习完了设计模式,在其中我们有了解到原型模式。这里涉及到了克隆自身对象。那么也就是对对象进行拷贝。这里就涉及到了这么一个概念。深
- idea spring Initializr创建项目勾选项目所需要的依赖pom.xml文件会加载勾选的依赖,也可以不勾选后面通过自己常用的p
- 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而
- 本文浅析了C#的复制和克隆技术,对于有需要的朋友可以参考下。在C#中,用HashTable,DataTable等实现复制和克隆,下面直接看例
- 在Mybatis的动态SQL和${}形式的参数中都用到了OGNL表达式。Mybatis常用的OGNL表达式如下1、e1 or e2:或<
- 1.Comparable前言,想要排序Student.有代码:import java.util.Arrays; class Stu
- 一般情况下SpringBoot以Jar包的形式进行打包打包 - jar包方式1、pom文件引入插件 <build> <pl
- 在使用手机时,蓝牙通信给我们带来很多方便。那么在Android手机中怎样进行蓝牙开发呢?本文以实例的方式讲解Android蓝牙开发的知识。&
- 背景知识Fluent Interface是一种通过连续的方法调用以完成特定逻辑处理的API实现方式,在代码中引入Fluent Interfa