最近总有小伙伴问类和对象的问题。感觉很多人还是不太明白这个道理,今天就先把这两个怪物杀了。HowtoGet20kInterviewCheatSheet类介绍一个Java程序是由若干个类组成的,一个类也是面向对象编程思想的具体实现。下面是类的定义:publicclassUser{//私有属性privateLonguserId;privateStringname;privateIntegerage;//构造方法publicUser(){}//剩余构造方法publicUser(LonguserId,Stringname,Integerage){this.userId=userId;这。name=name;this.age=age;}//公共方法publicvoidsay(){System.out.println("helloworld");}//外包装属性publicStringgetName(){returnthis.name;}}关键字导入三typessingle-typeimport当我们需要使用不同包下的类时,需要使用import来导入包或类,这时候就可以正常使用了。比如我们要使用java.util下的ArrayList,就必须使用importjava.util.ArrayList,代码如下://导入ArrayList类importjava.util.ArrayList;classTest{publicstaticvoidmain(String[]args){ArrayListlist=newArrayList();}}按需类型导入如果我们在同一个类中使用同一个包下的多个类,我们将使用按需类型导入。//使用java.util包目录下的List、ArrayList和LinkedList类//importjava.util.ArrayList;//importjava.util.LinkedList;//importjava.util.List;//如果你不想导入的类太多,可以直接导入包名。*importjava.util.*;publicclassTest{publicstaticvoidmain(String[]args){Listlist=newArrayList<>();Listlist1=newLinkedList();}}这只是一个外表,其实是一个一个导入的,只是在代码层面好像一下子导入了。静态导入import也可以导入静态方法和静态域的函数,比如下面的代码://**PreciseImport**//直接导入具体的静态变量、常量、方法和方法。注意import方法直接写方法名不带括号。importstaticcom.assignment.test.StaticFieldsClass.staticField;importstaticcom.assignment.test.StaticFieldsClass.staticFunction;//或者使用下面的形式://**按需导入**不需要指出static的导入方式成员名一一//importstaticcom.assignment.test.StaticFieldsClass.*;publicclassStaticTest{publicstaticvoidmain(String[]args){//上面的代码也可以直接写在这里,不用调用System.out.println(staticField);staticFunction();}}通过类名顺利执行,这也是import好玩的地方。构造方法构造方法也称为构造函数或构造函数。它的作用是类在初始化的时候会调用相应的构造方法,比如下面的代码:publicUser(LonguserId,Stringname,Integerage){this.userId=userId;this.name=name;this.age=age;}//公共方法publicvoidsay(){System.out.println("helloworld");}publicstaticvoidthink(){System.out.println("thinking");}//外包装属性publicStringgetName(){returnthis.name;}构造方法五原则构造方法必须同名作为班级;construction方法的参数可以没有也可以有多个;构造函数不能定义返回值(默认返回类型是类类型);每个类可以有一个或多个构造函数;构造函数总是与new操作一起使用。注意:如果没有显式定义构造函数,那么它会在编译时为它添加一个默认的构造函数。构造方法在实际开发中,一般用public修饰,当我们要单实例时,用private修饰。ObjectObject类是Java中的一个特殊类,它是所有类的父类,Java中的类都是直接或间接继承自Object类的。Object类的常用方法如下:equals():比较两个对象是否相同getClass():返回对象的运行时类hashCode():返回对象的哈希码值toString():返回对象的字符串wait():使当前线程等待notify():唤醒在此对象监视器上等待的单个线程notifyAll():唤醒在此对象监视器上等待的所有线程clone():克隆一个有关更新的新对象多对象内容,如clone(深克隆、浅克隆)、线程wait、notify、notifyAll的几个常用方法、对象比较、对象hashCode值等。继承Java只支持单继承:即一个子类可以只继承两个父类,一个父类可以被多个子类继承。每个人只能有一个亲生父亲,一个父亲可以有多个儿子。用法:使用extends关键字实现类继承。示例代码如下:}上面程序的执行结果:hello继承单继承的注意点。(Java不支持多重继承,通俗地说,一个子类只能有一个父类,一个父类可以有多个子类。)支持多层继承。(继承可以一直传递下去,子类有父类,父类有父类。。。)如果父类成员用private修饰,那么子类就不能继承了。(private只对本类有效)子类如果继承了父类的属性和方法,也可以拥有自己独有的属性和方法。(不仅有父类的属性(inheritable)和方法(inheritable),还有自己特有的属性和方法。)当子类和父类的成员变量同名时,子类优先.(就近原则)继承使用技巧将公共变量或方法提取到超类中;除非所有方法都有继承的意思,否则不要使用继承;当方法被覆盖时,不要改变原始方法的预期行为。一般在写代码的时候,发现代码中有重复的代码,需要向上抽取,考虑继承。当某个类的设计非常复杂时,可以考虑继承和代码复用的优点。可以使用继承轻松定义子类。父类的属性和方法可以在子类中使用(非私有修改)。设计应用程序变得更加容易。使用了很多设计模式,比如:模板方法模式,它使用继承,子类实现自己的业务逻辑。类和对象有什么区别?类是一个抽象的概念,是对某事物的描述;而对象是类的实例,类是真实的个体。例如:“人”是一个类(一个概念),老田(田伟昌)是一个真实的“对象”。注意:对象中有类对象,即Class对象,但类对象永远是对象,而不是类。不要混淆这两个概念。Java中可以实现多重继承吗?Java只能单继承,但可以实现多接口,支持多层继承。为什么Java不能实现多重继承?答:从技术实现的角度来说,是为了降低编程的复杂度。假设A类中有一个m()方法,B类中也有一个m()方法,如果C类同时继承了A类和B类,那么在调用C类的m()方法时就会产生歧义,这无疑会增加程序开发的复杂度,为了避免此类问题,Java语言规定不能继承多个类,但可以实现多个接口。覆盖和重载有什么区别?重写(Override)从字面上看,重写就是重写一遍。其实就是在子类中重写父类本身的方法。子类继承了父类原有的方法,但是有时候子类不想原封不动的继承父类中的某个方法,所以在方法名、参数列表、返回类型(子类中方法的返回值除外)当是父类中方法返回值的子类时),修改或重写方法体称为重写。但是需要注意的是,子类函数的访问修改权限不能小于父类。publicclassFather{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubSons=newSon();s.sayHello();}publicvoidsayHello(){System.out.println("Hello");}}classSonextendsFather{@OverridepublicvoidsayHello(){//TODOAuto-generatedmethodstubSystem.out.println("helloby");}}重写总结:1.发生在父类和子类之间2.方法名、参数列表、返回类型(子类中的方法除外返回类型为子类父类中的返回类型)必须相同3.访问修饰符的限制必须大于被覆盖方法的访问修饰符(public>protected>default>private)4.被覆盖的方法不能抛出Anewcheckedexceptionorawidercheckedexceptionthantheoverriddenmethod重载(Overload)在一个类中,如果同名方法有不同的参数列表(参数类型不同,参数个数不同甚至参数顺序不同)都被认为是重载.同时,重载对返回类型没有要求,可以相同也可以不同,但??是不能通过返回类型是否相同来判断重载。publicclassFather{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubFathers=newFather();s.sayHello();s.sayHello("wintershii");}publicvoidsayHello(){System.out.println("Hello");}publicvoidsayHello(Stringname){System.out.println("Hello"+""+name);}}重载总结:1.重载重载是类多态性的一种表现2.重载要求的参数列表同名方法不同(参数类型、参数个数甚至参数顺序)3、重载时,返回值类型可以相同也可以不同。返回类型不能作为区分重载函数的标准。为什么方法不能根据返回类型区分重载?答:因为在调用方法的时候,如果不指定类型信息,编译器就不知道你要调用哪个方法。例如下面的代码:floatmax(intx,inty);intmax(intx,inty);//方法调用max(1,2);因为max(1,2)没有指定返回值,编译器不知道调用哪个方法。施工方法有什么特点?答:构造方法的特点是:构造方法必须与类名相同;构造方法没有返回类型(默认返回本类的类型);构造方法不能被继承、重写、直接调用;定义时提供默认的无参构造方法;构造方法可以是私有的,私有构造方法不能用于对外创建对象。构造函数可以被覆盖吗?他们可以超载吗?构造函数可以被重载,但不能被覆盖。下面程序执行的结果是classExecTest{publicstaticvoidmain(String[]args){Sonson=newSon();}}classParent{{System.out.print("1");}static{System.out.print("2");}publicParent(){System.out.print("3");}}classSoextendsParent{{System.out.print("4");}static{System.out.print("5");}publicSon(){System.out.print("6");}}结果为:251346类加载顺序整体细分下面程序执行结果为?classA{publicintx=0;publicstaticinty=0;publicvoidm(){System.out.print("A");}}classBextendsA{publicintx=1;publicstaticinty=2;publicvoidm(){System.out.print("B");}publicstaticvoidmain(String[]args){AmyClass=新B();System.out.print(myClass.x);System.out.print(myClass.y);myClass.m();}}结果为:00B注意:在Java语言中,变量是不能被改写的。this和Java中的super有什么区别?this和super都是Java中的关键字,起参考作用,必须出现在构造方法的第一行。它们的区别如下。基本概念:this是访问本类的实例属性或方法;super是子类访问父类中的属性或方法。搜索范围:这个先查本类,没有再查父类;super直接访问父类。use:单独使用this时表示当前对象;super子类重写父类的方法时,访问的是父类的同名方法。this或super可以用在静态方法中吗?为什么?不能在静态方法中使用this或super,因为this和super引用的是需要创建的对象,而静态方法是在类加载时创建的,所以没办法在静态方法中使用this或super。使用静态方法需要注意哪些问题?使用静态方法需要注意以下两个问题:静态方法中不能使用实例成员变量和实例方法;this和super不能在静态方法中使用。final修饰符的作用是什么?final也是很多面试喜欢问的地方,但是我觉得这个问题很无聊。通常,最好回答以下5点:final修饰的类不能被final修饰的方法继承不能被重写final修饰的变量不能改变。如果一个引用被修改了,就意味着这个引用是不可变的,而这个引用指向的内容是可变的。对于被final修饰的方法,JVM会尝试内联它以提高运行效率final修饰的常量会在编译阶段存储在常量池中。此外,编译器必须为final字段遵循的两个重新排序规则更好:写入构造函数中的final字段,以及随后将对构造对象的引用分配给引用变量,不能在初始读取之间重新排序对包含最终字段的对象的引用以及对最终字段的后续初始读取。排序。经典使用场景:使用Integer、String等类。覆盖equals()方法时需要遵循哪些规则?Oracle官方文档对equals()的重写规则设置如下。自反性:x.equals(x)对任何非空引用值x返回true。对称性:对于任何非空引用值x和y,x.equals(y)必须返回与y.equals(x)相同的结果。传递性:对于任何非空引用值x、y、z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也必须返回值为true.一致性:对于任何非空引用值x和y,无论调用多少次x.equals(y),返回的结果都是一样的。在比较过程中,不能修改对象中的数据。对于任何非空引用值x,x.equals(null)必须返回false。这道题不需要背,知道大概意思就可以了,算是加分题。Object中的notify()和notifyAll()方法有什么区别?notify()方法随机唤醒一个等待线程,而notifyAll()方法将唤醒所有等待线程。如何使用clone()方法?如果在同一个类中使用,只需要实现Cloneable接口,定义或处理CloneNotSupportedException异常,参考如下代码:;ct.num=666;System.out.println(ct.num);CloneTestct2=(CloneTest)ct.clone();System.out.println(ct2.num);}}如果非内部类调用Forclone(),需要重写clone()方法,请参考如下代码:classCloneTestimplementsCloneable{intnum;publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{CloneTestct=newCloneTest();ct.num=666;System.out.println(ct.num);CloneTestct2=(CloneTest)ct.clone();System.out.println(ct2.num);}@OverrideprotectedObjectclone()throwsCloneNotSupportedException{returnsuper.clone();}}publicclassCloneTest2{publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{CloneTestct=newCloneTest();ct.num=666;System.out.println(ct.num);CloneTestct2=(CloneTest)ct.clone();System.out.println(ct2.num);}}对象克隆是原型模式的经典实现。java中创建对象的方法有哪些?Java提供了以下四种创建对象的方式:new通过反射机制创建新对象通过序列化机制采用clone机制顺便说一下有点挑战的东西。对于还是新手的同学来说,有些东西看不懂也没关系。范,不懂的人懂。每天保持学习的心态。一个月或一年后,如果你觉得回头看以前的你,如果你觉得当初自己傻,证明你进不去,如果和以前一样,证明你还是没有进步。需要反思。本文转载自微信公众号《Java后端技术全栈》,可通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。
