Java面向对象的三大特征:
封装、继承、多态
封装和继承几乎都是为多态而准备的
一、 封装
首先,属性能够描述事物的特征,方法能够描述事物的动作。封装就是把同一类事物的共性(包括属性和方法)归到同一类中,方便使用。
1.封装:封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据细节,只保留一些接口使其与外界发生联系。也就是说用户无需知道内部的数据和方法的具体实现细节,只需根据留在外部的接口进行操作就行。
2.封装的好处:
1) 实现了专业的分工
2) 良好的封装能够减少耦合
3) 类内部的结构能够自有修改
4) 可以对成员进行更精确的控制
5) 隐藏信息,实现细节
1.封装的步骤
1) 修改属性的可见性来限制对属性的访问
2) 为每个属性创建一队赋值和取值方法,用于对这些属性的访问
3) 在赋值和取值方法中,加入对属性的存取限制
为了实现良好的封装,我们通常将类的成员变量声明为private,在通过public方法来对这个变量来访问。对一个变量的操作,一般有读取和赋值2个操作,,我们分别定义2个方法来实现这2个操作,一个是getXX(XX表示要访问的成员变量的名字)用来读取这个成员变量,另一个是setXX()用来对这个变量赋值
二、 继承
- 1. Java继承
Java继承是面向对象的最显著的一个特征。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。JAVA不支持多继承,单继承使JAVA的继承关系很简单,一个类只能有一个父类,易于管理程序,父类是子类的一般化,子类是父类的特化(具体化)
继承所表达的就是一种对象类之间的相交关系,它使得某类对象可以继承另外一类对象的
数据成员
和成员方法。若类B继承类A,则属于B的对象便具有类A的全部或部分性质(数据属性)和功能(操作),我们称被继承的类A为
基类
、父类或
超类
,而称继承类B为A的
派生类
或子类。
继承避免了对一般类和特殊类之间共同特征进行的重复描述。同时,通过继承可以清晰地表达每一项共同特征所适应的概念范围——在一般类中定义的属性和操作适应于这个类本身以及它以下的每一层特殊类的全部对象。运用继承原则使得系统模型比较简练也比较清晰。
- 2. Java继承的特征
1) 继承关系是传递的。若类C继承类B,类B继承类A(多继承),则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。继承来的属性和方法尽管是隐式的,但仍是类C的属性和方法。
2) 继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。
3) 继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。
三、 多态
方法的重写、重载与动态连接构成多态性;
Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,派生类与基类间有IS-A的关系(即“猫”is a “动物”)。这样做虽然保证了继承关系的简单明了,但是势必在功能上有很大的限制,所以,Java引入了多态性的概念以弥补这点的不足,此外,抽象类和接口也是解决单继承规定限制的重要手段。同时,多态也是面向对象编程的精髓所在。
要理解多态性,首先要知道什么是“向上转型”。
我定义了一个子类Cat,它继承了Animal类,那么后者就是前者的父类。我可以通过
Cat c = new Cat(); 例化一个Cat的对象,这个不难理解。
但当我这样定义时: Animal a = new Cat();
这代表什么意思呢?
很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。所以,
父类引用只能调用父类中存在的方法和属性,不能调用子类的扩展部分;因为父类引用指向的是堆中子类对象继承的父类;(但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了。)
同时,父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
类的知识点
1.类的创建
【public】【类的类型】【final】【static
】 class 类名{
类的属性
类的方法
}
【public】修饰符是可选项,可写可不写,如果加上public修饰符,则本类所在文件名必须和类名相同。一个.java文件中可以有多个类,但只有一个用public修饰的类
【类的类型】,有三种类型,不写就是普通类。abstract代表抽象类。interface代表接口类。
【final】:是否是最终类,如果标识final,那么它就不能再被继承
【static
】:静态,表示类不用实例就可使用
修饰符的作用域:
2.方法的定义
方法的声明包含两部分,方法头和方法体。方法头的格式如下
【控制访问权】【abstract】【final】【static】【类型参数】返回类型 方法名(参数列表
)
控制访问权:就是上述中提到的修饰符作用域,如public
abstract:不能与final和private一起使用
final:是否是最终
static:静态,,不用实例话就可调用。程序加载时,会优先加载静态。
类型参数:可以是父类传入或传出。也可是没有返回值 void
3.实例化对象
类只是一种数据类型,需要实例化对象以后才能使用。类类型实例化对象需要两步,定义类对象变量,然后通过实例化类的对象来初始化对象变量。格式如下
类名称 类变量=new 类名称();
访问类中方法或属性通过:类变量.类属性或类方法
关于变量:
1.局部变量是定义在方法体中的变量,包括方法头中的参数在内。生命周期是在方法调用完就结束。
2.成员变量是定义在类中的变量,用以表述一个对象的状态信息。生命周期程序结束。
关于类的构造:
构造是类在被实例化时,默认调用的方法,它的定义是pubilc修饰符 方法名【方法名必须跟类名称相同】(参数【可选可不选】)如
S s=new S();调用的就是S类的public S(){};构造。
关于抽象类和接口类:
抽象类中的方法可以是抽象方法也可以是具体方法。
接口类中的方法必须是抽象方法。
关于类的回收机制:
自己百度
常见面试题:
1.静态块、动态块、构造函数、继承函数等的执行顺序
静态代码块 -> 继承函数->构造函数 ->动态块
2.重载和重写的区别
1.重写必须继承,重载不用。2.重写的方法名,参数数目相同,参数类型兼容,重载的方法名相同,参数列表不同。3.重写的方法修饰符大于等于父类的方法,重载和修饰符无关。4.重写不可以抛出父类没有抛出的一般异常,可以抛出运行时异常
3.单例模式、工厂模式的理解
单例模式分为:饿汉模式和懒汉模式
1.一个类有且仅有一个实例,并且自行实例化向整个系统提供
2.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提
高灵活性的目的
4.多态的具体表现
多态就是允许方法重名 参数或返回值可以是父类型传入或返回。
5.
JAVA常用设计模式
单例设计模式
工厂设计模式
代理设计模式
观察者设计模式
适配器模式
6
.Java是单继承还是多继承?使用接口的目的在哪里?
单继承
接口的作用就是把使用接口的人和实现接口的人分开,实现接口的人不必要关心谁去使用,而使用接口的人也不用关心谁实现的接口,由接口将他们联系在一起
7.
全局变量和局部变量的生命周期是怎么样的?作用域是什么?
全局变量:服务停的时候销毁
局部变量,在方法调用完就销毁
全局变量就是在类的整个范围之内,都有效的变量
局部变量就是在类中某个方法函数内或某个子类内,有效的变量
8
.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
可以
限制:
一个文件中只能有一个public类
并且此public类必须与文件名相同
9.
Java有没有goto?
1、java有goto2、但是java的goto是
保留字
3、
保留字
的意思就是不排除以后会启用,变成关键字。java有如下
保留字
:byValue, cast, future, generic, inner, operator, outer, rest, var , goto ,const
10.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
11
."=="和equals方法究竟有什么区别?
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
12
.静态变量和实例变量的区别?
在语法定义上的区别:
静态变量前要加static关键字,而实例变量前不加。
在程序运行时的区别:
实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。
静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码文件,不用创建任何实例象,静态变量就会被分配空间,静态变量就可以被使用了。
总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用
13.
是否可以从一个static方法内部发出对非static方法的调用?
不可以。因为非static方法要与对象关联在一起,必须创建一个对象后,才可以在该对象上进行方法的调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,一个static方法被调用时,可能还没有创建任何实例对象,所以,一个static方法内部不可以发出对非static方法的调用。
14
.请说出作用域public,private,protected,以及不写时的区别
Public作用域同一包/同一类/子类/不同包
Private作用域只在于同类中.
protected作用域同一包/同一类/子类
假如在定义的时候不写,系统默认会采用Public做修饰符
15.
.Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
Overload:重载
Override:重写
重载:同一个类中,方法名相同,参数列表不同。与返回值类型无关。
重写:存在于子父类,或者子父接口中,方法声明相同。
Overload的方法可以改变返回值的类型,因为它与返回值类型无关。
16
.面向对象的特征有哪些方面
抽象、继承、封装、多态性
17
.java中实现多态的机制是什么?
方法的重写Overriding和重载Overloading是Java多态性的不同表现.
重写Overriding是父类与子类之间多态性的一种表现
重载Overloading是一个类中多态性的一种表现.
18.
abstract class和interface有什么区别?
含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽 象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static fina
19.
什么是内部类?Static Nested Class 和 Inner Class的不同
内部类就是在一个类的内部定义的类,内部类中不能定义静态成员,内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法体中
在方法外部定义的内部类前面可以加上static关键字,从而成为Static Nested Class,它不再具有内部类的特性,所有,从狭义上讲,它不是内部类。Static Nested Class与普通类在运行时的行为和功能上没有什么区别,只是在编程引用时的语法上有一些差别,它可以定义成public、protected、默认的、private等多种类型,而普通类只能定义成public和默认的这两种类型。在外面引用Static Nested Class类的名称为“外部类名.内部类名”。在外面不需要创建外部类的实例对象,就可以直接创建Static Nested Class
20.
内部类可以引用它的包含类的成员吗?有没有什么限制?
完全可以。如果不是静态内部类,那没有什么限制
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员
21.
是否可以继承String类?
因为Sting是这样定义的:public final class String extends Object,里边有final关键字,所以不能被继承。
22.
垃圾回收的优点和原理。并考虑2种回收机制。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
23.垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是”可达的”,哪些对象是”不可达的”。当GC确定一些对象为”不可达”时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。