2019独角兽企业重金招聘Python工程师标准>>>

1、面向对象的特征

面向对象的三个基本特征:封装、继承、多态

封装

封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承

面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”。

被继承的类称为“基类”、“父类”或“超类”。

继承的过程,就是从一般到特殊的过程。

要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

继承概念的实现方式有三类:实现继承、接口继承和可视继承。

Ø         实现继承是指使用基类的属性和方法而无需额外编码的能力;

Ø         接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

Ø         可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。

在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。

抽象类仅定义将由子类创建的一般属性和方法,创建抽象类时,请使用关键字 Interface 而不是 Class。

OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。

多态

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

实现多态,有二种方式,覆盖,重载。

覆盖,是指子类重新定义父类的虚函数的做法。

重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

其实,重载的概念并不属于“面向对象编程”,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的(记住:是静态)。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!真正和多态相关的是“覆盖”。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态(记住:是动态!)的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚邦定)。结论就是:重载只是一种语言特性,与多态无关,与面向对象也无关!引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚邦定,它就不是多态。”

那么,多态的作用是什么呢?

我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

概念讲解

泛化(Generalization)

图表 1 泛化

在上图中,空心的三角表示继承关系(类继承),在UML的术语中,这种关系被称为泛化(Generalization)。Person(人)是基类,Teacher(教师)、Student(学生)、Guest(来宾)是子类。

若在逻辑上B是A的“一种”,并且A的所有功能和属性对B而言都有意义,则允许B继承A的功能和属性。

例如,教师是人,Teacher 是Person的“一种”(a kind of )。那么类Teacher可以从类Person派生(继承)。

如果A是基类,B是A的派生类,那么B将继承A的数据和函数。

如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能和属性。

若在逻辑上B是A的“一种”(a kind of ),则允许B继承A的功能和属性。

聚合(组合)

图表 2 组合

若在逻辑上A是B的“一部分”(a part of),则不允许B从A派生,而是要用A和其它东西组合出B。

例如,眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,不是派生(继承)而成。

聚合的类型分为无、共享(聚合)、复合(组合)三类。

聚合(aggregation)

图表 3 共享

上面图中,有一个菱形(空心)表示聚合(aggregation)(聚合类型为共享),聚合的意义表示has-a关系。聚合是一种相对松散的关系,聚合类B不需要对被聚合的类A负责。

组合(composition)

图表 4 复合

这幅图与上面的唯一区别是菱形为实心的,它代表了一种更为坚固的关系——组合(composition)(聚合类型为复合)。组合表示的关系也是has-a,不过在这里,A的生命期受B控制。即A会随着B的创建而创建,随B的消亡而消亡。

依赖(Dependency)

图表 5 依赖

这里B与A的关系只是一种依赖(Dependency)关系,这种关系表明,如果类A被修改,那么类B会受到影响。

感谢:http://blog.csdn.net/cancan8538/article/details/8057095

2、final, finally, finalize 的区别

1、final修饰符(关键字)。被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。被final声明的方法也同样只能使用,不能重载。

【例】

public  class  finalTest{
final   int  a=6;//final成员变量不能被更改
final   int  b;//在声明final成员变量时没有赋值,称为空白final
public finalTest(){
b=8;//在构造方法中为空白final赋值
}
int   do(final x){//设置final参数,不可以修改参数x的值
return x+1;
}
void  doit(){
final int i = 7;//局部变量定义为final,不可改变i的值
}
}

2、finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。

3、finalize是方法名。java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

感谢:http://blog.csdn.net/cyl101816/article/details/67640843

3、Java的Integer和int有什么区别

Java是面向对象的编程语言,一切都是对象,但是为了编程的方便还是引入了基本数据类型,为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换,对应如下:

原始类型:boolean,char,byte,short,int,long,float,double

包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

顺便一提,Java中的基本数据类型只有以上8个,除了基本类型(primitive type),剩下的都是引用类型(reference type)。

所以最基本的一点区别是:Ingeter是int的包装类,int的初值为0,Ingeter的初值为null。除此之外还有区别,请看代码:

[java] view plain copy

  1. public class TestInteger {
  2. public static void main(String[] args) {
  3. int i = 128;
  4. Integer i2 = 128;
  5. Integer i3 = new Integer(128);
  6. System.out.println(i == i2); //Integer会自动拆箱为int,所以为true
  7. System.out.println(i == i3); //true,理由同上
  8. Integer i4 = 127;//编译时被翻译成:Integer i4 = Integer.valueOf(127);
  9. Integer i5 = 127;
  10. System.out.println(i4 == i5);//true
  11. Integer i6 = 128;
  12. Integer i7 = 128;
  13. System.out.println(i6 == i7);//false
  14. Integer i8 = new Integer(127);
  15. System.out.println(i5 == i8); //false
  16. Integer i9 = new Integer(128);
  17. Integer i10 = new Integer(123);
  18. System.out.println(i9 == i10);  //false
  19. }
  20. }

为什么i4和i5比是true,而i6和i7比是false呢?关键就是看valueOf()函数了,这个函数对于-128到127之间的数,会进行缓存, Integer i4 = 127时,会将127进行缓存,下次再写Integer i5 = 127时,就会直接从缓存中取,就不会new了。所以i4和i5比是true,而i6和i7比是false。

而对于后边的i5和i8,以及i9和i10,因为对象不一样,所以为false。

以上的情况总结如下:

1,无论如何,Integer与new Integer不会相等。不会经历拆箱过程,new出来的对象存放在堆,而非new的Integer常量则在常量池(在方法区),他们的内存地址不一样,所以为false。

2,两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。因为java在编译Integer i2 = 128的时候,被翻译成:Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存。

3,两个都是new出来的,都为false。还是内存地址不一样。

4,int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比。

感谢:http://blog.csdn.net/login_sonata/article/details/71001851

4、重载和重写的区别

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

方法的重写规则

  • 参数列表必须完全与被重写方法的相同;
  • 返回类型必须完全与被重写方法的返回类型相同;
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为final的方法不能被重写。
  • 声明为static的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个方法,则不能重写这个方法。

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

只能重载构造函数

重载规则

  • 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准
区别点 重载方法 重写方法
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)

总结

方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载是一类中多态性的一种表现。

5、抽象类和接口有什么区别
接口和抽象类都是继承树的上层,他们的共同点如下:
1) 都是上层的抽象层。
2) 都不能被实例化
3) 都能包含抽象的方法,这些抽象的方法用于描述类具备的功能,但是不比提供具体的实现。
他们的区别如下:
1) 在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。
2) 一个类只能继承一个直接父类,这个父类可以是具体的类也可是抽象类;但是一个类可以实现多个接口。
Java语言中类的继承是单继承原因是:当子类重写父类方法的时候,或者隐藏父类的成员变量以及静态方法的时候,JVM使用不同的绑定规则。如果一个类有多个直接的父类,那么会使绑定规则变得更复杂。为了简化软件的体系结构和绑定机制,java语言禁止多继承。
接口可以多继承,是因为接口中只有抽象方法,没有静态方法和非常量的属性,只有接口的实现类才会重写接口中方法。因此一个类有多个接口也不会增加JVM的绑定机制和复杂度。
对于已经存在的继承树,可以方便的从类中抽象出新的接口,但是从类中抽象出新的抽象类就不那么容易了,因此接口更有利于软件系统的维护和重构。

图中如果Sparrow继承类Bird 类 ,Boyin继承Airplane类,Sparrow 和Boyin想使用同样的flay方法那么是没有办法实现的,因为类的继承是单继承。

https://pic3.zhimg.com/v2-1f71b697cfd213ce382a35ee73790730_r.jpg
如果Bird和Airplane是接口那么Boyin想使用同样的flay方法就很简单了。在写一个接口让Sparrow和Boyin实现这个接口就可以了如下图:

作者:天天向上
链接:https://www.zhihu.com/question/20149818/answer/142270191
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

6、说说反射的用途及实现

反射(Reflection)是Java程序开发语言的特征之一。它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。Oracle官方对反射的解释是:

Reflection enables Java code to discover information about the fields,methods and constructors of loaded classes,and to use reflected fields, methods, and constructors to operate on their underlying conunterparts, within security restrictions.

The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a give class. It also allows programs to suppress default reflective access control.

简而言之,通过反射,我们可以在运行时获得程序或者程序集中每一个类型的成员和成员的信息。

程序中一般的对象的类型都是在编译器就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译器是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。

反射的核心是JVM在运行时才动态的加载类或者调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行的对象是谁。

Java反射框架主要提供以下功能:

1、在运行时判断任意一个对象所属的类

2、在运行时构造任意一个类的对象

3、在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)

4、在运行时调用任意一个对象的方法

反射的主要用途:

反射最重要的用途是开发各种通用的框架。

基本运用

1、获取Class对象

2、判断是否为某个类的实例

3、创建实例

4、获取方法

5、获取构造器信息

6、获取类的成员变量(字段)信息

7、调用方法

8、利用反射创建数组

感谢:http://www.sczyh30.com/posts/Java/java-reflection-1/#%E4%B8%80%E3%80%81%E5%9B%9E%E9%A1%BE%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AF%E5%8F%8D%E5%B0%84%EF%BC%9F

转载于:https://my.oschina.net/u/1170450/blog/1633716

2018年面试准备汇总相关推荐

  1. BaiDu往年面试题目汇总☆WM☆

    BaiDu往年面试题目汇总☆WM☆祝自己明天能取得一个好的面试成绩 题目来源:http://www.cnblogs.com/cutepig/archive/2007/09/14/893552.html ...

  2. Java面试总结汇总

    Java面试总结汇总,整理了包括Java基础知识,集合容器,并发编程,JVM,常用开源框架Spring,MyBatis,数据库,中间件等,包含了作为一个Java工程师在面试中需要用到或者可能用到的绝大 ...

  3. tcp当主动发出syn_一文读懂TCP四次挥手工作原理及面试常见问题汇总

    简述 本文主要介绍TCP四次挥手的工作原理,以及在面试中常见的问题. 字段含义 seq序号:Sequence Number,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行 ...

  4. npm install 报错 汇总_2020年特岗教师招聘征集志愿人员资格复审、面试公告汇总...

    原标题:2020年特岗教师招聘征集志愿人员资格复审.面试公告汇总 昨天晚上 安徽省2020年特岗教师招聘空缺计划征集志愿拟参加面试人员名单已经公布啦,接下来陆续就是资格复审和面试啦 小可爱们一点要关注 ...

  5. 复旦计算机考研复试要口试吗,2017复旦大学考研复试:英语口语面试常见问题汇总...

    2017复旦大学考研复试:英语口语面试常见问题汇总本站小编 辅仁网/2017-12-29 A magazine publisher is trying to decide how many magaz ...

  6. docker及k8s容器面试精华汇总(一),祝大家顺利通过企业面试!

    docker及k8s容器面试精华汇总,希望可以加深大家对容器的理解,祝大家顺利通过企业面试. 一.如何在 Kubernetes 中实现负载均衡? node中有kube-proxy,他可以提供负载均衡. ...

  7. 面试中 项目遇见的难点答案_你和offer之间只差这几个面试问题!常见面试问题汇总...

    99%的人都会大呼"坑爹"的面试问题,你真的知道该怎么回答吗? 记得第一次面试的时候,面试官对简历也很满意,前面都聊的好好的,最后问了一句简历上没有的内容:你的职业规划是什么?我一 ...

  8. 1.面试题目汇总-嵌入式篇

    1.面试题目汇总-嵌入式篇 https://blog.csdn.net/qq_33443989/article/details/76938304 2017年08月08日 20:18:10 Fogost ...

  9. 北航计算机学院往年夏令营+考研面试题目汇总

    北航计算机学院硕士复试机经+面经: 北航计算机学院往年夏令营+预推免机试题目汇总 北航计算机学院往年夏令营+考研面试题目汇总 北航计算机学院往年夏令营+考研面试数理题目汇总 以下是我在网络上找到的北航 ...

最新文章

  1. Linux系统(一)文件系统、压缩、打包操作总结
  2. IntelliJ IDEA2016 + tomcat 即改即生效 实现热部署
  3. python变量类型-Python-变量类型
  4. [TPYBoard - Micropython之会python就能做硬件 2] 利用micropython控制NOKIA 5110屏
  5. scrapy-redis
  6. Asp.Net Core对接钉钉群机器人
  7. java windows 2008_Windows server 2008 R2 安装Java环境
  8. Hihocoder 最近公用祖先三 在线LCA
  9. 中国的脑部研究--脑网络组图谱
  10. 一文读懂机器学习、数据科学、人工智能、深度学习和统计学之间的区别
  11. 老李分享:持续集成学好jenkins之解答疑问
  12. php下获取客户端IP
  13. 继电器触点RC吸收电路
  14. Django中的DateTimeField和DateField
  15. SM3密码算法 - Python实现
  16. 【SJTUOJ笔记】P1125 Typist (NOI2001 聪明的打字员)
  17. IOC和AOP概念理解
  18. mysql服务无法启动1053错误已解决
  19. virsh查询虚拟机列表
  20. python编写会计凭证金蝶_会计凭证应该如何录入的方法

热门文章

  1. PHP的OB缓存(输出缓存)
  2. C语言-07其它相关
  3. 操作系统复习之进程描述和控制
  4. SVN提示: File or directory '*' is out of date; try updating 解决方案
  5. 关于百万用户服务器架构能力(一)QQ游戏服务器架构
  6. 提高MySQL性能的方法
  7. AndroidStudio_安卓原生开发_什么是AndroidStudio NDK ---Android原生开发工作笔记140
  8. 大数据之-Hadoop之HDFS_NameNode故障处理_NameNode元数据恢复_案例---大数据之hadoop工作笔记0073
  9. 大数据之-Hadoop之HDFS_HDFS组成架构---大数据之hadoop工作笔记0050
  10. ES6新特性_let使用案例---JavaScript_ECMAScript_ES6-ES11新特性工作笔记004