面向对象简介
- 面向对象程序设计(object oriented programming 简称OOP)
- 对象是一个由信息(变量)及对信息进行处理(方法)的描述,其本质是对现实事物的特征和变化规律建立的模型。
面向对象三要素
封装
- 将成员变量设置为私有,然后提供get和set方法给外界访问。
- 优点:
- 能够减少耦合
- 隐藏实现细节等信息
- 安全
this关键字
- this关键字,表示当前类的对象
- this关键字在程序中三种常见的用法:
- 通过 this 关键字可以明确地去访问一个类的成员变量,解决与局部变量名称冲突的问题;
- 通过 this 关键字调用成员方法;
- 构造方法是在实例化对象时被Java虚拟机自动调用的,在程序中不能像调用其他方法一样去调用构造方法,但是可以在一个构造方法中去使用 "this([参数1,参数2…])"的形式去调用其他构造方法。
- 使用 this 调用类的构造方法时需要注意以下几点:
- 只能在构造方法中使用 this 关键字去调用其他的构造方法,不能在成员方法中使用this关键字调用构造方法;
- 在构造方法中,使用 this 关键字调用构造方法的语句必须放在第一行,且只能出现一次;
- 不能在一个类的两个构造方法中使用 this 互调,这种写法会编译报错。
访问控制修饰符
继承
- 所有类都有父类,即所有类都派生于Object类
- 只能单亲继承,即每一个子类只能有一个父类
- 子类只能继承父类的非private修饰的变量和方法
super关键字
- 表示当前类的父类对象
- 可以使用super关键字实现对父类变量和方法的访问
- super()和this()不能同时用
重写
- 重写发生在子父类当中
- 方法名、参数列表均相同
- 返回值类型必须相同或相容。(或是其父类返回值类型的子类)
- 子类方法的访问权限不能缩小
- 静态方法(static)不能进行重写(因为静态资源只加载一次)
重载
- 发生在同一个类中
- 方法名相同
- 参数列表不同(个数,数据类型,顺序),注意:参数列表不同跟变量名称没关系
- 返回值的类型是否改变,跟方法是否重载没关系,不能作为重载的依据
实例
- 通过C实例的父类方法调用重写方法,还是用C实例确认范围。
public class Test {
public static void main(String[] args) {
A a = new A();
a.fun();
C c = new C();
c.fun();
A cc = new C();
cc.fun();
}
}
class AA{
public void pick(){
System.out.println("AA pick");
}
}
class A extends AA{
public void fun(){
System.out.println("A");
pick();
}
}
class B extends A{
@Override
public void pick(){
System.out.println("B pick");
}
}
class C extends B{
}
多态
- 代码当中体现多态性,其实就是一句话: 父类引用指向子类对象
抽象类
- 抽象类不能被实例化。
- 抽象类不一定有抽象方法,有抽象方法一定是抽象类。
- 非抽象类继承抽象类,需要实现父类所有抽象方法。
- 抽象类可包含抽象方法、非抽象方法(包括构造方法)以及变量。
- 抽象方法不能有方法体。
public abstract class Main(){
public int x;
public abstract void fun();
public void fun2(){
}
}
接口
- 一个接口可以extends多个接口
- 一个类只能extends一个类,但是可以implements多个接口
- 一个类同时声明继承父类和继承接口时,先extends再implements
- 接口内只能存在final常量和抽象方法
- 接口内的方法一定默认用public abstract修饰,且public abstract可省略不写。
- 接口内的变量一定默认用public final static修饰,且public final static可省略不写。
public interface Interf1 {
int x = 1;
void fun();
}
public class Main extends Fu implements Interf1, Interf2{
@Override
public void fun() {
}
}
public class Test {
public static void main(String[] args) {
AB ab = new D();
A a = new C();
A aa = ab;
E e = new E(ab);
}
}
interface A{
}
interface B{
}
interface AB extends A, B{
}
class C implements A{
}
class D implements AB{
}
class E{
E(){
}
E(A a){
System.out.println("a");
}
}
内部类
public class Main {
class In1{
}
static class In2{
}
public static void main(String[] args) {
ArrayList list = new ArrayList<String>(){
@Override
public String toString() {
String str = "";
for (String s: this){
str += s;
}
return str;
}
};
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
}
}
类型转换
向上转型
- 子类引用赋值给父类引用称为向上转型,此时,类型转换是自动进行的。
- 通过父类引用无法访问子类特有的方法,而且在调用父类方法时,优先使用子类重写覆盖的方法。
Fu z = new Zi();
向下转型
- 父类引用赋值给子类引用,称为向下转型。此时,需要强制类型转换。
Fu z = new Zi();
Zi zz = (Zi)z;
final
- 表示最终的、不可修改的,用来修饰变量、方法、类。
- 用法:
- final修饰的类不能够被继承;
- final修饰的方法不能被重写;
- final修饰的变量称为为常量,常量名称规定必须都为大写
- final在声明一个常量时,必须给常量赋值,完成初始化。
- final修饰基本数据类型,则该变量的值不能被改变
- final修饰引用数据类型(对象),则该对象的引用(内存地址)不能被改变,即对其初始化之后便不能再让其指向另一个对象。
static
- static关键字,表述为“静态的,全局的”,被static修饰的资源(变量或方法),可以直接通过类名调用,而不需要实例化
- 用法:
- static声明的资源只能被初始化一次,在整个程序编译通过之后,开始运行之前完成初始化。
- 修饰变量,称为静态变量。局部变量不能被static修饰,因为static有全局的意思。
- 修饰方法,称为静态方法。静态方法只能调用静态资源,不能调用this和super,因为静态资源的加载先于实例化。
- 被static修饰的变量和方法独立于该类的任何对象。也就是说,它不依赖于特定的实例,被该类的所有实例共享。
- 修饰内部类,称为静态内部类。不需要外部类实例化,可以通过外部类名直接调用。
JVM的类加载顺序
- static声明的静态资源 > new > {代码块} > 构造方法constructor