一、面向对象概念
1、对象:是类的实例,一般存在与堆;
2、对象的引用:是类的实例的地址,一般存在与栈中;
3、面向对象是一种思想,分析对象以及对象之间的关系,设计合理的模型,编程实现;
4、面向对象三大特征:
封装:
把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节;
作用:提高了程序的可复用性和可维护性,
把对象的私有数据和公共数据分离开,保护了私有数据,
减少了可能的模块间干扰,达到降低程序复杂性、提高可控性的目的。
继承:
从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力;
单继承:类与类之间
多继承:接口与接口之间
实现:类实现接口(多个接口)
优势:
减小代码和数据的冗余度,大大增加程序的重用性
多态:
同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果;
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载;
作用:
消除类型之间的耦合关系
二、类与接口
1.类
数据类型,描述了具有相同特性的和行为的对象集合;
2.构造方法
方法名与类名必须相同,参数不能相同(参数个数或同一位置的参数类型不同),并且没有返回值,在对象创建时被调用;
3.方法重载与方法重写的区别
方法重载:
同一个类中,方法的名字相同,但参数个数、参数的类型不同,与返回类型无关
方法重写:
子类和父类的关系,子类重写了父类的方法,但方法名、参数类型、参数个数必须相同
4.接口
抽象方法和常量值定义的集合,是一种特殊的抽象类;
接口特点:
接口中的抽象方法必须是public abstract方法;
接口中的变量必须是public static final类型的;
接口没有构造方法,不能被实例化;
接口中不能含有静态块和静态方法;
接口可以继承多个接口,一个类可以实现多个接口(implements);
类如果实现了一个接口,就必须实现接口里面的所有抽象方法,除非这个类被定义为抽象类;
5.抽象类
包含抽象方法的类,可以拥有成员变量和成员方法;
抽象类特点:
抽象方法必须是public(默认)或者protected的;
抽象类是有构造方法的,但不能用来创建对象;
抽象类可以有静态代码块和静态方法;
一个类只能继承一个抽象类;
如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法,除非这个类被定义为抽象类;
6.内部类
静态内部类:
类定义时加上static关键字;
只能访问外部类的静态成员变量与静态方法
生成静态内部类对象的方法:OuterClass.InnerClass inner = new OuterClass.InnerClass();
成员内部类:
成员内部类可以访问外部类的静态与非静态的方法和成员变量;
生成成员内部类对象的方法:OuterClass.InnerClass inner = new OuterClass().new InnerClass();
在局部内部类中访问外部类的成员变量的方法:OuterClass.this.a;
局部内部类:
类似于局部变量,不能定义为public,protected,private或者static类型;
定义方法中,只能方法中声明为final类型的变量。
匿名内部类:
匿名内部类没有类名,没有class关键字也没有extends和implements等关键字修饰;
匿名内部类会隐式地继承一个父类或实现一个接口
匿名内部类使用得比较多,通常是作为一个方法参数
匿名类会生成OuterClass$1.class文件...
使用内部类最吸引人的原因是:
每个内部类都能独立地继承自一个(接口的)实现,
所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。
从这个角度看,内部类使得多重继承的解决方案变得完整。
接口解决了部分问题,而内部类有效地实现了“多重继承”。
三、修饰符与关键字
1.访问权限(修饰符)
修饰类:public default abstract & final(内部类:protected private)
修饰方法:public static protected private final & abstract(只能在抽象的类中) default
修饰变量:public static protected private final transient & volatile default
修饰符 | 同一类 | 同一包 | 子孙类 | 其他包 |
public | 可以访问 | 可以访问 | 可以访问 | 可以访问 |
protected | 可以访问 | 可以访问 | 可以访问 | 不可访问 |
default | 可以访问 | 可以访问 | 不可访问 | 不可访问 |
private | 可以访问 | 不可访问 | 不可访问 | 不可访问 |
2.关键字static
方便在没有创建对象的情况下来进行调用(方法/变量)
静态变量:
被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化;
使用场景:
对象之间共享数据、访问方便
静态方法:
静态方法不依赖于任何对象就可以进行访问;
在静态方法中不能访问类的非静态成员变量和非静态成员方法
使用场景:
在不创建对象的情况下调用某个方法
静态代码块:
静态代码块在类加载的时候只会执行一次,因此可以用来优化程序性能;
使用场景:
避免同类对象或者资源被创建或者使用多次,造成空间浪费;
静态内部类:
直接使用 外部类名.内部类名 访问;
静态内部类只能访问外部类的静态属性和方法;
只有将某个内部类修饰为静态类,然后才能够在这个类中定义静态的成员变量与成员方法
使用静态内部类的好处:
加强了代码的封装性以及提高了代码的可读性
静态导包:
Java包的静态导入,用import static;
好处:
可以简化一些操作
3.关键字final
final变量:
对于一个final变量,
如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
匿名内部类中使用外部的局部变量只能是final变量,不是同一个变量,final保证变量一致性;
final方法:
final修饰的方法是不能被重写的
final类:
final修饰的类不能被继承
4.关键字transient
transient只能修饰成员变量;
被transient关键字修饰的变量不再能被序列化;
静态变量不管是否被transient修饰,均不能被序列化;
5.关键字volatile
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(使用volatile关键字会强制将修改的值立即写入主存,工作内存中缓存变量的的缓存行无效,会去主存读取)
2)禁止进行指令重排序。(它确保指令重排序时不会把其后面的指令排到内存屏障(volatile修饰的变量)之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成)
volatile修饰的变量在多线程中不能保证原子性(synchronized,Lock,AtomicInteger(基本数据类型)可以保证原子性),能保证可见性,在一定程度上保证有序性;
使用场景:
使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值(例如:public void setFlag() { flag = true;})
2)该变量没有包含在具有其他变量的不变式中(操作的仅仅是变量本身)
单例模式的double check
6.关键字synchronized
当一个线程正在访问一个对象的synchronized方法,那么其他线程不能访问该对象的其他synchronized方法。
当一个线程正在访问一个对象的synchronized方法,那么其他线程能访问该对象的非synchronized方法。
如果一个线程执行一个对象的非static synchronized方法,另外一个线程需要执行这个对象所属类的static synchronized方法,此时不会发生互斥现象(因为访问static synchronized方法占用的是类锁,而访问非static synchronized方法占用的是对象锁,所以不存在互斥现象。)
7.关键字native
java调用本地接口用的;
Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
可以将native方法比作Java程序同C程序的接口,其实现步骤:
a.在Java中声明native()方法,然后编译;
b.用javah产生一个.h文件;
c.写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
d.将第三步的.cpp文件编译成动态链接库文件;
e.在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
JAVA本地方法适用的情况:
a.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问;
b.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的;
c.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
8.关键字this
9.关键字super
10.关键字strictfp
修饰类和方法,精确浮点;
当JAVA虚拟机进行浮点运算时,如果没有指定strictfp关键字时,JAVA的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以致于得到的结果往往无法令你满意。
使用了strictfp来声明一个类、接口或者方法时,那么所声明的范围内JAVA的编译器以及运行环境会完全依照浮点规范IEEE-754来执行。
因此如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字strictfp。
当一个class或interface用strictfp声明,内部所有的float和double表达式都会成为strictfp的。
可以将一个类、接口以及方法声明为strictfp,但是不允许对接口中的方法以及构造函数声明strictfp关键字
三、操作符与流程控制
四、初始化与清理