一、面向对象的三大特性?
1)、面向对象
面向对象是一种程序设计思想,计算机程序的设计实质上就是将现实中的一些事物的特征抽离出来描述成一些计算机事件的过程,这种抽象的过程中,我们把具体的事物封装成一个一个的整体进行描述,使被描述的对象具备一些系统性、整体性的的行为和特征,我们把这种设计思想称为面向对象。
2)、面向对象与面向过程
2.1)、面向过程是早期的程序语言设计思想,该思想强调事物的行为细节,即程序的设计不需要封装成一个个的整体,而是将整个程序描述成一个行为,所有行为细节都按照固定方式一步一步的执行,执行程序就是执行某一行为的过程。
2.2)、面向对象和面向过程都是一种思想,面向对象是相对于面向过程而言的,
面向过程强调的是具体的功能行为,而面向对象将功能封装进对象,强调具备了功能的对象,面向对象是基于面向过程的,但面向对象思想更接近于现实场景。
三大特性
封装和继承几乎都是为多态而准备的
一)、封装
首先,属性能够描述事物的特征,方法能够描述事物的动作。封装就是把同一类事物的共性(包括属性和方法)归到同一类中,方便使用。
封装:封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据细节,只保留一些接口使其与外界发生联系。也就是说用户无需知道内部的数据和方法的具体实现细节,只需根据留在外部的接口进行操作就行。
封装的好处:
1)实现了专业的分工
2)良好的封装能够减少耦合
3)类内部的结构能够自有修改
4)可以对成员进行更精确的控制
5)隐藏信息,实现细节
封装的步骤
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)继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。
继承的作用:
(1)父类具备的方法子类可以直接继承过来,不用重新书写,提高了代码的复用性
(2)让类与类之间产生关系,有了关系才有多态的实现
(3)Java中只支持单继承,不支持多继承,因为多继承存在安全隐患(当多个父类存在同个功能时,子类不确定要运行哪一个),Java支持多层继承,即父类还可以继承其他类,java用另一种机制解决单继承的局限性,即多实现
继承的特点
覆盖(重写)
如果子父类中的成员一致时,子类成员会覆盖父类成员
当子类继承父类时,沿袭父类的功能到子类中,但子类对该功能的实现细节不一致,子类可以保留父类对该功能的定义,重写功能的内容
覆盖与重载:重载只看参数列表,其他一致参数列表不一致为重载,而重写子父类的参数必须要一致
this与super
this表示当前对象的引用,super表示当前对象父类的引用
子父类中的构造函数
构造函数不能重写
构造函数第一行有一条隐式的语句super()/this()
在对子类对象进行初始化时,父类构造函数也会运行,因为子类中的构造函数默认第一行有一条隐式的super()语句,这样方便子类构造时先获取到父类的共性属性
super()一定要定义在子类构造函数的第一行,当没有默认的空参数构造函数,要手动指定
注意事项:
千万别为了获取其他类中的功能而继承,必须是类与类间有所属关系才可以继承。
子类覆盖父类时必须保证子类权限大于等于父类,才可以覆盖,否则编译失败
子类静态成员只能覆盖父类静态成员
final关键字
final关键字可以修饰类、函数和变量
被final修饰的类不可以被继承
被final修饰的方法不可以被复写
被final修饰的变量只能被赋值一次,既可以修饰成员变量,也可以修饰局部变量;
Object类
java中有一个特殊的类,Object类,它是所有对象的超类(根类),Object类中定义了所有对象的共性成员
Object类中的方法
equals() 比较两个对象是否相同
toString() 返回该对象的字符串表示形式
getClass() 获取该对象对应的字节码文件对象
hasCode() 获取该对象的哈希码值
类间的体系关系
继承、聚集(聚合)、组合
继承:
指的是一个类继承另外的一个类的功能,并增加它自己的新功能或改写旧有功能的具体实现,继承是类与类之间最常见的关系。
聚合:
指的是整体与部分的关系。通常在定义一个整体类后,再去分析这个整体类的组成结构。从而找出一些组成类,该整体类和组成类之间就形成了聚合关系。例如足球队中的足球队员就是聚合关系。
组合:
也表示类之间整体和部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在。部分对象与整体对象之间具有共生死的关系。例如人的各个身体器官之间的关系。
三)、多态
方法的重写、重载与动态连接构成多态性;
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类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。所以,
父类引用只能调用父类中存在的方法和属性,不能调用子类的扩展部分;因为父类引用指向的是堆中子类对象继承的父类;(但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了。)
同时,父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
二、类与对象的关系?
对象:是具体的事物。
类:是对对象的抽象。
先有具体的对象,然后抽象各个对象之间象的部分,归纳出来类,通过类再认识其他对象。
对象是类的实例化。将对象的公有的功能和属性抽象出来成为一类的具有普遍行为和属性的类。
三、类的组成部分?
成员变量、成员方法、构造器、代码块
四、重载与重写的区别?
重载是方法名相同,但形参不同(形参个数或者形参类型),与方法的修饰符与返回值类型无关。它是在一个类中,而重写是在一个子类中,因为重写的前提是要有继承。
五、四种访问修饰符?
六、内部类?
Java中的内部类共分为四种:
静态内部类static inner class (also called nested class)
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class
静态内部类Static Inner Class
最简单的内部类形式。
类定义时加上static关键字。
不能和外部类有相同的名字。
被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。
只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
生成静态内部类对象的方式为: OuterClass.InnerClass inner = new OuterClass.InnerClass();
成员内部类Member Inner Class
成员内部类也是定义在另一个类中,但是定义时不用static修饰。
成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。
成员内部类就像一个实例变量。 它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
在外部类里面创建成员内部类的实例: this.new Innerclass();
在外部类之外创建内部类的实例: (new Outerclass()).new Innerclass();
在内部类里访问外部类的成员: Outerclass.this.member
方法内部类Local Inner Class
匿名内部类Anonymous Inner Class 匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements,没有构造方法。 匿名内部类隐式地继承了一个父类或者实现了一个接口。 匿名内部类使用得比较多,通常是作为一个方法参数。 生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。
七、接口与抽象类的区别?
八、this关键字?
this表示当前对象的引用,super表示当前对象父类的引用
This可以修饰方法、属性或构造器。
九、super关键字?
this表示当前对象的引用,super表示当前对象父类的引用
Super对父类方法、属性或构造器的引用。
总结:(存在继承关系的前提下)在使用有参构造器实例化子类的对象时,需要为子类的构造器传入参数,而在子类构造器发挥作用之前,父类的构造器也要使用参数进行实例化,所以需要同时传入父类的参数的值,这也就解释了我为何要在子类的有参构造器中写入了父类构造器的参数了。(当然也可以不这么做,另外一种方式把父类有参数构造器中的参数定义为static的变量,然后在super()中将其名称写入,也可以达到一样的效果)
十、static关键字?
十一、什么是值传递?什么是引用传递?
首先要说明的是java中是没有指针的,java中只存在值传递,只存在值传递!!! 然而我们经常看到对于对象(数组,类,接口)的传递似乎有点像引用传递,可以改变对象中某个属性的值。但是不要被这个假象所蒙蔽,实际上这个传入函数的值是对象引用的拷贝,即传递的是引用的地址值,所以还是按值传递。
String是final修饰的,不可变的。
十二、是否可以在static环境中访问非static变量或方法?
不能:
static变量在java中是属于类的,在类的所有实例中,它的值都是一样的。在类被JVM载入时,静态变量的值就确定了。
而非静态变量是属于实例的,要在new一个实例之后,值才会存在。
在static环境中,调用非static变量,可能这个变量都还不存在,当然会出错。
详细回答:
不可以,在static环境中,不可以访问非static。因为静态的成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以访问非静态的成员。类的加载先于实例的创建,因此静态环境中,不可以访问非静态!
十三、什么是自动拆箱跟自动装箱?
Java 1.5中引入了自动装箱和拆箱机制:
(1)自动装箱:把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质,可以调用toString()、hashCode()、getClass()、equals()等方法。
如下:
Integer a=3;//这是自动装箱
其实编译器调用的是static Integer valueOf(int i)这个方法,valueOf(int i)返回一个表示指定int值的Integer对象,那么就变成这样:
Integer a=3;=>Integer a=Integer.valueOf(3);
(2)拆箱:跟自动装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为基本类型的数据。
如下:
int i = new Integer(2);//这是拆箱
编译器内部会调用int intValue()返回该Integer对象的int值
注意:自动装箱和拆箱是由编译器来完成的,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。
http://blog.csdn.net/jackiehff/article/details/8509056
十四、java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?构造函数能否被重写?
当新对象被创建的时候,构造函数(与类名相同,public修饰的函数)会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数。
Java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。
Java不支持像C++中那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java不会创建默认的复制构造函数。
不能被重写,但是能被重载,因为构造器不能被继承。