您的位置:首页 > 编程语言 > Java开发

JAVA面向对象知识点详解

2016-12-15 14:13 211 查看

一、类和对象

类:类是对对象的一种抽象描述,也就是说,类其实就是定义对象的一个模板,在这个模板里面充分描述了对象所具有的属性和行为(方法)

 

对象:通过类具体创建出来的实体,就是对象,这些对象是可以拿来使用的,一个类可以创建出任意个相同的对象(也就是一对多关系)

 

所以,在编写代码时,必须先编写类(Class),然后通过这个Class来创建对象,创建对象使用new关键字(例如:People p = new People())

二、类加载器和加载过程

我们都知道,当我们编写完一个类以后,需要通过javac编译成成对应的class字节码文件(也就是将java源文件编译成二进制的字节码文件)

 

概念:

当运行一个Java程序的时候,JVM(Java虚拟机)首先要做的事情就是类加载。类加载是通过类加载器(ClassLoader)来完成的。当类加载加载完class文件以后,会对这个class文件创建一个Class对象。Class对象就是在内存中队字节码文件的一个具体描述,以后创建的所有实例,都是由这个Class对象来创建的,每一个class文件对应着一个Class对象,这个Class对象是有JVM创建的。

 

1)Java中的类加载器主要分为三类:

     BootClassLoader(启动类加载器,主要是用于加载JRE\lib文件夹下的jar文件,其中有一个是rt.jar包,这个jar包含了JDK的核心类库。这个类加载器是使用C++语言编写的,所以在Java程序中不能直接使用它,因此这个类加载器是由JVM在启动时创建来使用的。) 

    

    ExtClassLoader(扩展类加载器,它主要用于加载jre\lib\ext目录下的jar文件,这个目录下是jre的扩展类库)

     AppClassLoader(系统类加载器,它主要用于加载classpath下的class文件以及jar包,通常我们自己编写的类都是由这个加载器来完成的)

2)这三个类加载器的加载顺序:

在加载一个class的时候,是基于双亲委模型来加载的,

AppClassLoader首先会调用ExtClassLoader来加载,ExtClassLoader又会委托给BootClassLoader来加载,

当父类加载器不能加载该class的时候,又会让其子类来加载,

当所有加载器都
4000
不能加载这个class文件时,就会引发一个ClassNotFoundException异常,表示无法找到该类文件。

三、JVM的内存分配

JVM在运行时将内存分为三大块:

1).栈

栈是遵循先进后出的原则(先入栈的变量最后才出栈)。

局部变量都是在栈中分配的,如果变量是基本数据类型,那么这个变量的值一并存放在栈中。如果是引用数据类型,那么在栈中存放的只是一个引用地址,这个地址是指向堆中的对象首地址。

 

2).堆

只要通过new关键字创建出来的对象,都会分配到堆中,每个对象在堆中都会有一个唯一的地址,这个地址可以被栈中的变量所引用。

堆中的对象通常存放实例变量,实例变量是随着对象的创建而创建,也随着对象的销毁而销毁,每个实例都有自己的实例变量,他们之间是互不影响的,不会产生共享。

(注意:在参数传递的过程中,如果参数的类型是基本数据类型,那么传递过去的就是基本数据类型的值,如果参数的类型是引用数据类型,那么传递过去的是一个引用地址的值,这个引用地址同样是指向堆中的同一个对象)

关于垃圾货收:当堆中的任何一个对象没有引用指向它的时候,这个对象就被视为垃圾对象,JVM会在定期去自动回收它,并释放内存。

 

3).方法区

方法区中通常用于存放类加载的class信息(字段信息,方法信息,类的信息,接口信息,还包括静态变量,以及常量等等)当这些信息加载到方法区后,jvm就会根据这些信息构建一个Class对象


四、封装、继承、多态

1、封装:

隐藏内部的细节,对外提供某种访问的方式。通常实现封装的手段我们都会使用访问修饰符。

包的封装,控制当前包中的哪些类可以被其他包中的类去访问

通常我们在定义一个class的时候都会使用访问修饰符public。(注意:class只能使用public或者是默认的,也就是不需要任何访问修饰符),没有使用public修饰的类,只能被本包中其他类去访问,不能被其他包中的类去访问

类成员的封装,将属性和行为封装在一个类中,并且也可以通过访问修饰符来控制他们的访问权限

行为本身也具备封装的特性,把实现的细节隐藏,对于调用者而言,内部的实现是透明的。

 

 

2、继承:

继承是一种父与子的关系,继承的好处在于将子类共性的东西提取到父类中,让子类做更少的事情,因此达到代码的复用性,这样使整个结构更加清晰。(继承是一种is a的关系)

 Java中只能是单继承的关系,也就是一个子类只能有一个父类,但是一个父类有多个子类的。

在java中所有类的默认父类都是Object。

在继承的时候,使用extends关键字。

 

3、多态:

一个对象具有多种形态的表现,多态的前提是必须有继承。因为在不同场合或者业务场景中,子类是可以替代父类来完成具体的某件事情。

1)引用多态

     父类的引用类型,子类的对象

2)行为上的多态

     通常在子类中会重写父类的方法,来完成具体的功能。

编译时看父类,运行时看子类(编译的时候看下父类有没有定义这个方法,运行时看子类有没有重写这个方法,如果子类重写,则优先调用子类重写的方法,如果没有重写,则调用继承父类而来的方法)

 

4、关于重写和重载的区别

1)重载,方法名相同,参数的个数和类型不同,对返回值不要求,这就是重载,重载既可以发生在本当中,也可以发生在父类和子类当中。构造方法也是可以重载的。

2)重写(覆盖),方法名相同,参数的个数和类型也必须相同,返回值也必须相同。重写只能发生在父类和子类当中。
 

五、抽象类和接口

1、抽象类:

当一个类不能具体去描述一个对象的时候,我们就认为它是抽象的。因此抽象类是不能用来创建实例来使用的,主要用来被继承。

1)抽象类可以有自己的构造方法

2)抽象类可以有具体的方法

3)抽象类可以有抽象方法,必须使用abstract关键字修饰,这个方法必须由子类来实现。

4)抽象类不能使用new关键字来创建实例

5)定义抽象类必须使用abstract关键字声明

6)当一个类中只要有一个抽象方法,这个类就必须是抽象类

7)抽象类可以定义实例变量和静态变量以及常量 

8)抽象类可以再继承抽象类,也可以继承普通的类

 

2、接口:

接口是比抽象类更为抽象的一个组件,它主要是用于定义行为的标准。因此接口是用来被实现的,使用implements关键字。

1)接口只能定义常量

2)接口只能定义抽象方法

3)接口只能继承接口,不能继承普通的类和抽象类

4)接口是没有构造方法的

 

3、注意:

1)在接口中定义常量时,可以不用final static修饰,因为编译器在编译时会自动加上。

2)在接口中定义抽象方法时可以省略abstract关键字,编译器在编译时同样会加上。

当然了,面向对象还远远不止这些,上面的只是最最基本的知识点总结了一下,后续还会补充。。。希望各位大牛们补充
 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: