一、面向过程与面向对象
面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。而面向对象是模型化的,抽象出一个类,需要什么功能直接使用,不必知道这个功能如何实现、怎样实现;但面向对象的底层还是面向过程,把面向过程抽象成类,然后封装,方便我们使用。
二、Java面向对象三大特性
封装、继承、多态
封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性;
继承:提高代码复用性,继承是多态的前提;
多态:提高了程序的拓展性;
实现多态的两种形式:继承(多个子类对同一方法的重写)、接口(实现接口并覆盖接口中同一方法)
实现多态的三个必要条件:继承、重写、向上转型
三、抽象类与接口
相同点:1.接口和抽象类都不能实例化
2.都位于继承的顶端,用于被其他类实现或继承
3.都包含抽象方法,其子类都必须复写这些抽象方法
不同点:
参数 | 抽象类 | 接口 |
声明 | 抽象类使用abstract关键字声明 | 接口使用interface关键字声明 |
实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现 | 子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
访问修饰符 | 抽象类中的方法可以是任意访问修饰符 | 接口方法默认修饰符是public。并且不允许定义为 private 或者 protected |
多继承 | 一个类最多只能继承一个抽象类 | 一个类可以实现多个接口 |
字段声明 | 抽象类的字段声明可以是任意的 | 接口的字段默认都是 static 和 final 的 |
其他 | 有构造方法、成员变量、常量、普通方法、抽象方法 | 抽象方法、常量、普通方法(jdk1.8) |
普通类和抽象类的区别:
- 普通类不能包含抽象方法,抽象类可以包含抽象方法、普通方法
- 普通类可以直接实例化,抽象类不能直接实例化
- 抽象类不能被final修饰,因为定义抽象类就是为了让其他类继承
四、变量与方法
成员变量与局部变量区别
储存位置:
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中;
局部变量:在方法被调用时或语句被执行时存在,当方法调用完后或语句执行完后就自动释放,存储在栈内存中
初始值:
成员变量:有默认初始值;
局部变量:没有默认初始值,使用前必须赋值;
无参构造的作用:帮助子类做初始化工作
五、内部类
将一个类的定义放在另一个类的内部,即为内部类;内部类本身就是类的一个属性,与其他属性定义方式一致。
内部类可以分为四种:成员内部类、局部内部类、匿名内部类、静态内部类
静态内部类:定义在类内部的静态类就是静态内部类。
public class Outer {
private static int radius = 1;
static class StaticInner {
public void visit() {
System.out.println("visit outer static variable:" + radius);
}
}
}
静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量,静态内部类的创建方式:new 外部类.静态内部类(),如下
Outer.StaticInner inner = new Outer.StaticInner();
inner.visit();
成员内部类:定义在类的内部成员位置上的非静态类即为成员内部类,如下
public class Outer {
private static int radius = 1;
private int count =2;
class Inner {
public void visit() {
System.out.println("visit outer static variable:" + radius);
System.out.println("visit outer variable:" + count);
}
}
}
成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,创建方式为:外部类实例.new 内部类(),如下:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.visit();
局部内部类:定义在方法中的内部类即为局部内部类。
public class Outer {
private int out_a = 1;
private static int STATIC_b = 2;
public void testFunctionClass(){
int inner_c =3;
class Inner {
private void fun(){
System.out.println(out_a);
System.out.println(STATIC_b);
System.out.println(inner_c);
}
}
Inner inner = new Inner();
inner.fun();
}
public static void testStaticFunctionClass(){
int d =3;
class Inner {
private void fun(){
// System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
System.out.println(STATIC_b);
System.out.println(d);
}
}
Inner inner = new Inner();
inner.fun();
}
}
定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类()
,如下:
public static void testStaticFunctionClass(){
class Inner {
}
Inner inner = new Inner();
}
匿名内部类:匿名内部类就是没有名字的内部类,日常开发中使用的比较多。
public class Outer {
private void test(final int i) {
new Service() {
public void method() {
for (int j = 0; j < i; j++) {
System.out.println("匿名内部类" );
}
}
}.method();
}
}
//匿名内部类必须继承或实现一个已有的接口
interface Service{
void method();
}
匿名内部类创建方式:
new 类/接口{
//匿名内部类实现部分
}
匿名内部类的特点:
- 匿名内部类必须继承一个抽象类或者实现一个接口
- 匿名内部类不能定义任何静态成员和静态方法
- 当所在方法的形参需要被匿名内部类使用时,必须声明为final
- 匿名内部类不能是抽象的,必须实现所继承类或实现接口的所有抽象方法
内部类的优点:
- 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
- 内部类不为同一包的其他类所见,具有很好的封装性;
- 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
- 匿名内部类可以很方便的定义回调。
局部内部类和匿名内部类访问局部变量时,为什么变量必须加上final?
public class Outer {
void outMethod(){
final int a =10;
class Inner {
void innerMethod(){
System.out.println(a);
}
}
}
}
为什么要加final呢?是因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。
六、重写与重载
1.构造方法不能被继承,所以不能重写,可以被重载
2.方法的重写和重载都是实现多态的方式,区别在于重载实现的是编译时的多态性,而重写实现的是运行时的多态
3.重载:发生在同一个类中,方法名相同而参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,所以重载的方法不能根据返回类型区分
4.重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出异常小于等于父类,访问修饰符大于等于父类。(private和构造方法不能继承,static、final、private、构造方法不能重写)
七、对象相等判断
1)==和equals的区别
==的作用是判断两个对象的地址是不是相等,即判断两个对象是不是同一个对象(基本数据类型==比较的是值,引用数据类型==比较的是内存地址)
equals()方法没有被重写时比较的是该类的两个对象,等价于==;重写后则比较两个对象的内容是否相等。
注:对象的相等与指向他们的引用相等有什么不同?
对象的相等,比较的是内存中存放的内容是否相等,而引用相等比较的则是他们指向的内存地址是否相等。
八、Java包
JDK中常用的包有哪些?
- java.lang:这个是系统的基础类;
- java.io:包含所有与输入输出有关的类,比如文件操作等;
- java.nio:为了完善io包中的功能,提高io包中性能而写的一个新包;
- java.net:包含与网络有关的类;
- java.util:包含系统辅助类,特别是集合类;
- java.sql:包含数据库操作的类;