java是面向对象的编程语言,那么让我们来回答一下下面的问题:
- 什么是对象;
- 对象和类有什么不同;
- 什么是面向对象的编程;
- 什么是面向对象的编程语言;
- 面向对象编程的基本特性有哪些,请分别说明;
如果你是一个工作多年的java程序员,你肯定对这些问题不陌生并且有自己的独特理解,但是如何将大脑中的概念用通用的语言来描述出来却是大部分程序员的软肋。所以我根据自己的理解将大脑中的概念进行整理,给出我认为通俗易懂的描述;
什么是对象?
万事万物皆对象,事物都有自己的属性和功能。所以具有特定属性和功能的事物被称为对象;
对象和类有什么不同?
具有特定属性和功能的事物被称为对象,而类是对对象属性和功能的抽象(归纳和具体展现形式);
什么是面向对象的编程?
面向对象的编程是一种编程范式或编程风格,它以对象或者类作为组织代码的基本单位,并以封装、抽象、继承、多态作为代码设计和实现的基础;
什么是面向对象的编程语言?
支持类或对象的语法机制,并有现成的语法机制来实现面向对象编程的特性(封装、抽象、继承、多态)的语言;
面向对象编程的特性有哪些,请分别说明?
封装
封装通俗来讲就是数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过已经提供的方式来操作对象的属性和方法;通过封装可以提高可读性、可维护性、易用性以及方便维护和拓展;
抽象
狭隘的抽象是指隐藏方法的具体实现,让调用者只关心方法的定义;广义的抽象更是一种设计思想,方法命名、面向接口编程、设计模式等都是抽象的实践;
继承
继承表示的是一种is-a的关系,通过extends来关联多个类,子类可以复用父类提供的某些属性和方法;通过继承可以实现代码的复用也更符合人类对现实事物的认知;
多态
狭隘的多态是指子类可以替换父类并允许重写父类的方法,其实多态可以表现为接口实现多态和继承重写多态两种形式;多态的特性能提高代码的可拓展性和复用性;
严格来说封装、抽象、继承、多态并不能给出单独的定义,他们是对面向对象编程的不同特性的具体阐述;
面试问题补充:
1.方法命名如何体现抽象或者多态的?
比如接口中有个图片上传到阿里云的方法,我们可以定义为uploadImgAliyun(),想象一下如果以后又需要上传腾讯云的话是不是应该定义一个uploadImgTencent()方法?其实我们可以将方法名定义为uploadImg()方法,具体上传的哪里由具体的实现类或者子类来实现,这是抽象或者多态的一种实现形式;
2.jvm是如何实现多态的?
其实面试官想问的是jvm是如何实现父类的引用指向子类的?
在jvm中和多态相关的两个指令invokevirtual和invokeinterface,分别对应着继承多态和接口实现多态;
3.方法重载和方法重写
方法重载:是指方法名相同,但参数列表不同,重载和返回类型是无关的;
方法重写:是java多态的表现,大多是发生在父类与子类之间,即子类重写父类中的方法。
重写要求方法名相同,访问权限不能低于父类,抛出的异常不能更多;
4.java中的动态解析和静态解析
Class文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址。这个特性给Java带来了更强大的动态扩展能力,使得可以在类运行期间才能确定某些目标方法的直接引用,称为动态解析;(多态的实现就是动态解析的具体实现)
也有一部分方法的符号引用在类加载阶段或第一次使用时转化为直接引用,这种转化称为静态解析。在Java语言中,符合“编译器可知,运行期不可变”
这个要求的方法主要有静态方法和私有方法两大类
,前者与类型直接关联,后者在外部不可被访问,这两种方法都不可能通过继承或别的方式重写出其他的版本,因此它们都适合在类加载阶段进行解析。
参考资料补充:
C++中的间接调用与直接调用,JVM抽象成了4个指令来完成
- invokevirtual:咱们平时写代码调用方法,最常用的就是这个指令。这个指令用于调用public、protected修饰,跟多态机制有关。
- invokeinterface:多态调用时,如果父类引用是对象,就用invokevirtual。如果父类引用是接口,就用这个。
- invokespecial:只用于调用私有方法,构造方法。与多态机制无关。
- invokestatic:只用于调用静态方法。与多态机制无关。