当前位置: 首页 > 后端技术 > Java

说说对象和类,JAVA中的this、super和static关键字

时间:2023-04-01 23:17:11 Java

Java对象到底是什么?对象:对象是具有状态和行为的类的实例。类:类是描述一类对象的行为和状态的模板。比如人是一个类,它的状态包括:姓名、性别、身高、体重等,它的行为:吃饭、睡觉、聊天、运动等。publicclassPerson{/***statusorattribute*/Stringname;//名称Stringsex;//genderintheight;//heightintweight;//weight/***Behavior*/publicvoidsleep(){System.out.println(this.name+"--"+"sleep");}publicvoideat(){System.out.println("Eat");}publicvoidDance(){System.out.println("Dance");}}对象是指具体的人,比如“小张”就是对象,可以通过newpublicstaticvoidmain(String[]args){Personzhang=newPerson();zhang.name="小张";zhang.sex="男";张.height=180;zhang.weight=150;}通过上面的例子我们可以发现,面向对象提出了一种解决计算机世界复杂软件工程的方法论,拆解问题的复杂性,从人的思维。因为是面向过程的,让计算机一步步做一件事情,这是一种程序化的叙事思维,简单明了。然而,随着软件项目越来越大,人们发现面向过程语言开发在软件维护和软件重用方面存在着巨大的困难。创建对象的过程一般来说,我们可以通过new来创建一个对象,比如上面例子中的那句话:Personzhang=newPerson();虽然我们写的时候是一句简单的语句,但是JVM内部实现过程是复杂的:当将硬盘指定位置的Person.class文件加载到内存中执行main方法时,为main方法在栈内存中打开(push-to-stack),然后在main方法的栈区分配创建了一个变量zhang。执行new,在堆内存中开辟一个实体类空间,分配一个内存首地址值,调用实体类对应的构造函数,并初始化(如果没有构造函数,Java会添加一个默认构造函数)。将实体类的首地址赋值给zhang,变量zhang就会指向实体。(指向这个对象)当创建多个对象时,内存发生变化。当我们新建多个对象时,属性会开辟额外的堆空间用于存储,方法只有一种,不会额外消耗内存。让我们看一个例子:publicstaticvoidmain(String[]args){Personming=newPerson();名.name="名";明.睡眠();Personwang=newPerson();wang.name="王";王。sleep();}运行结果:ming--sleepwang--睡眠对象ming的属性在堆内存,方法在方法区。当我们通过Person类添加一个wang对象时,栈内存中会有一个对象名wang指向堆内存中另一个新创建的Person对象,属性存放在堆内存中。我们可以看到对象ming和对象wang属性互不影响,相互独立。但是对象ming和对象wang的方法区是共享的。那为什么两者的属性输出结果不一样呢?其实方法就像是一套指令模板,任何人都可以传入数据给它执行,然后得到相应的执行结果。但是JVM如何确保ming.sleep();返回的结果是小明在睡觉而不是小王在睡觉还是其他情况?Java的this其实就是解决这个问题的,后面慢慢说。无处不在的this和super关键字this表示对当前对象的引用,可以理解为指向对象本身的“指针”,但JAVA中没有指针的概念。我们知道,在C/C++中,一个指针指向内存中的一个地址,这个地址就是存储变量的值。这个地址存储的变量值是“public”,这里的“public”是指拥有这个地址的变量。他们可以随时访问这个地址的内容,并可以修改它。一旦修改,指向这个地址的所有变量的值也会改变。C++也有结构体和对象的概念,但为什么没有像Java一样有“封装”的概念呢?因为指针在c和c++中非常强大,可以通过指针直接访问和操作内存中的数据。Java没有指针,所以封装可以大大提高安全性。虽然java中没有指针的概念,但是this("pointer")无处不在。从上面的例子我们可以看出publicvoidsleep(){System.out.println(this.name+"--"+"sleep");ming.sleep()和wang.sleep()语句调用的代码在方法区是同一块内存,但是在JVM运行过程中,调用sleep()可以根据是哪个对象,方法used成员变量数据使用哪个对象的数据。this的本质就像在方法中传递参数一样,隐式传递thisthis表示当前对象的引用:this。属性区分成员变量和局部变量this.()调用本类的方法this()表示调用本类的构造函数,只能在构造方法的第一行使用。this关键字只能出现在非静态修改的代码中,我们来看一个例子:北京北京=新北京();}}publicclassCountry{字符串名称;publicCountry(){//构造函数System.out.println(this.getClass().getName());}}publicclassBeijingextendsCountry{}publicclassNanjingextendsCountry{}结果:com.company.Nanjingcom.company.Beijing子类Nanjing和Beijing什么都不做,只是通过父类Country的构造函数获取子类的名字.当程序执行newNanking()语句实例化子类时,会隐式调用父类的构造函数,相当于:publicclassNanjingextendsCountry{publicNanking(){super();//显式调用在父类的构造函数}}的过程中,this会被隐式传递,否则不会显示各个子类的名字。让我们修改南京班的代码:publicclassNanjingextendsCountry{publicNanjing(){System.out.println("南京自定义构造函数");}}Result:com.company.Nanjingnanjing自定义构造函数我们可以看到:如果子类Nanjing自定义构造函数,会先调用父类的构造函数,再调用自己的构造函数。让我们看看super关键字super。最近的父类。super表示父类对象:super。attribute表示父类对象super中的成员变量。method()表示父类对象中定义的方法super()表示调用父类构造方法时可以指定参数,如super("Nanjin");任何构造方法的第一行默认为super();可以写,不写会隐式调用super();super()只能用在构造方法的第一行。this()和super()都只能出现在构造的第一行,所以只能选其一。编写this()不会隐式调用super()。super关键字在子类中显式调用父类中重写的非静态成员方法和成员变量下面看一个super调用父类方法的例子:classFather{voidmessage(){System.out.println("这是父亲");}}classSonextendsFather{voidmessage(){System.out.println("这是儿子");}voiddisplay(){消息();超级消息();}}classMain{publicstaticvoidmain(Stringargs[]){Sons=newSon();s.显示();}}结果:ThisissonThisisfather可以看出super和this的功能差不多,主要区别:this指向当前对象,super指向离自己最近的父类,所以不会深入了解它。为什么static关键字这么特殊Java中的static`关键字主要用于内存管理,可以用来修饰变量或者方法。由于JAVA面向对象随处可见,在面向对象的思想下,方法和对象之间存在很强的耦合性。简单地说,没有对象就不能调用方法。static关键字就是为了解决这个问题而设计的。让我们看一个例子:publicclassCountry{Stringname="china";publicvoidshow(){System.out.println(名称);}}publicstaticvoidmain(String[]args){Countryc1=newCountry();国家c2=新国家();c1.name="中国新";c2.show();}结果:如果china修饰为static:publicclassCountry{staticStringname="china";publicvoidshow(){System.out.println(名称);}}结果:chinanew我们可以看到,如果给一个属性加上static,那么这个属性就不再属于某个对象,而是属于一个类。所有对象共享,通过类对象名和变量名可以访问同一个静态属性,例如:Country.nanme当程序进行类加载时,静态方法随着类加载一起加载到JVM中,而这时候并不是没有对象实例化优先于对象创建。静态属性在单独的内存区,不在新的对象内存中。另外,一般来说,静态方法是不能访问实例变量的。其实Java在调用静态方法的时候是不会传this的。没有这个,它无法处理差异。数据。非静态方法可以调用静态方法,但是静态方法不能调用非静态方法求助。本篇到此就结束了,非常感谢你能看完,如果觉得文章对你有帮助,别忘了关注我哦!更多精彩文章计算机内功、JAVA底层、面试相关资料等更多精彩文章在公众号「小牛吹吹吹」