02 面向对象

二、面向对象

1.概述

一种思想: 面向过程==》面向对象

执行者==》指挥者

例子:结合实际场景

对象、方法 (只要结果)

特点:
1. 封装 (encapsulation)
2. 继承 (inheritance)
3. 多态 (polymorphism)

2.类和对象关系

1)概述

找对象、建立对象、使用对象。维护对象的关系

类:对现实生活中事物的描述
对象:这类事物实实在在存在的个体。

2)成员变量和局部变量

比较 成员变量 局部变量
作用范围 整个类 函数、语句中
内存位置 堆内存 栈内存

3)匿名对象

new Car();
null

3.封装(Encapsulation)

private(最小权限):私有修饰符,权限修饰符。
类中用于成员变量、成员函数、类中有效
setAge(int a);
getAge();
注意:私有仅仅是封装的一种表现形式
隐藏属性,提供访问方法。

4.类

1)构造函数

特点:

函数名与类名相同
不定义返回值类型、无return
运行一次

2)构造代码块

作用:给对象初始化
优先于构造函数执行。

3)this关键字

this.name = name;
可以区分局部变量与成员变量同名问题。
this 指当前对象(所在函数所属对象的引用)
this.show();
但凡本类功能内部使用本类对象皆用this
构造函数调用构造函数也用this()
this语句只能定义在构造函数第一行。

4)static

静态,只用于修饰成员(成员变量、成员函数)
修饰后,可被对象调用,也可被类名调用(正宗)
特点:
1. 随类加载而加载
2. 优先对象存在
3. 被所有对象共享
4. 可直接被类名调用
5. 随类生,随类死,生命周期长

实例变量与类变量的区别

比较 实例变量 类变量
存在位置 堆内存 方法区
生命周期 短,随对象消失 长,随类消失

注意事项:

静态方法只能访问静态成员,非静态方法可以访问静态成员。
静态方法中不可以定义this、super关键字
主函数是静态的
* 利:对对象的共享数据进行单独存储,节省空间。
可直接被类名调用。
* 弊:生命周期过长,访问出现局限性(只能访问静态)。

5)主函数

public static void main(String[] args)
{
}
//JVM传入new String[0];

java MainDemo ha ha ha //后面是传入的数组

6)什么时候使用静态

共享数据时
当功能内部没访问到非静态数据时

7)工具类

将构造函数私有化(private)
将方法静态化(static)
将不暴露方法私有化(private)

8)静态代码块

static
{
。。。。//最先运行,仅类加载运行一次
}
{
。。。。//其次运行,对象创建时运行一次
//叫做构造代码块
}

9)javadoc

/** @param arr 接收一个int类型数组 @return 返回最大值 */

javadoc -d myhelp -author -version ArrayTool.java
必须是public类
public、protected默认提取
参考API文档

5.对象

1)对象的初始化过程

  1. 先找到.class文件并加载到内存
  2. 执行类中static代码块(若有)
  3. 在堆内存开辟空间,分配内存地址
  4. 在堆内存建立对象特有属性,默认初始化
  5. 显式初始化
  6. 对对象进行构造代码块初始化
  7. 构造函数初始化
  8. 将内存地址给p

2)对象调用成员

02 面向对象_第1张图片

6.单例设计模式

  1. 将构造函数私有化
  2. 在类中创建一个本类对象(私有)
  3. 提供一个方法可以获取到该对象
    1. 懒汉式(延迟加载)
    2. 饿汉式(开发中用、简单安全)
//懒汉式,对象延迟加载
class Single{
    private Single(){}
    private static Single s = null;
    public static Single getInstance(){
        if(s == null){//双重判断
            synchronized(Single.class){//同步锁
                if(s == null)
                    s = new Single();
            }
        }
        return s;
    }
}
//饿汉式
class Single{
    private Single(){}
    private static Single s = new Single();
    public static Single getInstance(){
        return s;
    }
}

7.继承和接口

1)继承

提取共性描述,单独描述

extends 所属关系才继承

提高代码的 复用性
让类与类之间产生关系,也才有多态特性。
Java只支持 单继承 ,支持 多层继承 。
所谓多继承用 接口 (应该叫 多实现
使用继承体系,先查阅父类描述,创建子类使用功能

2)组合

聚集:has a
聚合: 球队和球员
组合: 人和收

3)子父类特点

1.子父类 变量 同名

默认访问本类,可用super访问父类。

2.子父类 方法 同名

覆盖,运行子类内容(重写Overrider)

特点:子类权限 大于等于 父类,静态覆盖静态。
重写:子父类一模一样
重载:看同名函数的 参数列表

3.构造函数

父类构造函数 super() // 隐式调用
this和super 只能存在其一

子类中至少会有一个构造函数访问父类构造函数

super的使用和this的使用几乎一致。
this代表的是本类对象的 引用 。
super代表的是父类对象的 引用 。

4)final关键字

1.修饰类、函数、变量
2.被final修饰的类 不可以被继承
3.被final修饰的函数 不可以被复写
4.被final修饰的变量 是常量 ,只能被赋值 一次 。
常量全大写,如:PI、MY_PI
public static final double PI =3.14159;
5. 内部类 定义在类中局部位置上时,只能访问该局部被 final修饰的局部变量

5)抽象类

abstract class Person{
     abstract void sleep();
}

抽象类比一般类多了抽象方法。
不可以实例化,不可以被继承。

抽象类比一般类多个了 抽象函数 。就是在类中可以定义抽象方法。
抽象类不可以实例化

特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

abstract 关键字,和哪些关键字不能共存
1. final :被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
2. private : 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。
而抽象方法出现的就是需要被复写。
3. static :如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。可是抽象方法运行没意义。

6)模板方法设计模式

在定义功能时,功能的一部分是确定的,一部分是不确定的,确定的部分使用不确定的。将不确定的部分暴露出去,由该类的子类完成。

获取时间:System.currentTimeMillis();

02 面向对象_第2张图片

7)接口

格式:
1.常见定义:常量,抽象方法
2.固定修饰符:常量 public static final
方法 public abstract
记住:接口中成员都是public的

interface Inter
{
}
class Test implements Inter
{
}

区别于继承,全抽象,子类要实现。
可以多实现(类似多继承)。

先继承(但继承)后实现(多接口)

接口和接口之间 继承关系,可以多继承( 仅仅 存在于这里)。
类与类之间 继承关系。
类与接口之间 实现关系。

接口的特点:

  1. 对外暴露的规则
  2. 程序的功能扩展,降低耦合性
  3. 用来多实现
  4. 类可以实现多个接口,仅能继承一个类
  5. 接口间可以多继承

继承:is(是,所属于)
接口(实现):更灵活 like(像)

抽象类和接口异同:
相同:
1. 都可以在内部定义抽象方法。
2. 通常都在顶层。
3. 都不可以实例化,都需要子类来实现。

不同点:
1. 抽象类中可以定义抽象方法和非抽象方法,
而接口中只能定义抽象方法。
2. 接口的出现可以多实现。
抽象类只能单继承。
也就是说:接口的出现避免了单继承的局限性。
3. 继承和实现的关系不一致。继承:is a,实现:like a

8.多态

1)多态概述

事物存在的多种体现形态。
1. 多态 的体现
Animal c = new Cat();
父类的引用指向了自己的子类对象
父类的引用可以接收自己的子类对象。

public void function(Animal a)
{
}
  1. 前提
    instanceof (判断关系)
    必须是类与类间有关系(继承、实现)
    存在覆盖。
  2. 好处
    大大提高程序的扩展性
  3. 弊端
    只能使用父类的引用访问父类成员
  4. 应用
    简化对象调用。

2)多态中成员的特点

编译时期:参阅引用型变量所属的类中是否有调用方法。
运行时期:参阅对象所属的类中是否有调用的方法。

成员函数: 在多态调用时,编译看左边,运行看 右边 。
成员变量: 无论编译运行都看引用型变量所属的类( 左边 )。
静态成员变量: 无论编译运行都参考 左边 。
静态绑定
动态绑定

3)Object类–equals()

instanceof 判断,优先

4)toString()

hashCode()
getClass().getName()

5)CURD

c create r read u update d delete

9.内部类

1)内部类概述

  1. 内部类 可以直接访问 外部类 中的 成员 , 包括私有
  2. 外部类要访问内部类要构建内部类 对象 。

    之所以可以直接访问外部类中的成员,是因为内部类中持有外部类的 引用 (外部类名。this)可被 private 修饰
    访问格式:
    1. 当内部类定义在外部类的成员位置上,而且 非私有, 可以在外部其他类中。
    可以 直接建立内部类对象。
    格式
    外部类名.内部类名 变量名 = 外部类对象.内部类对象;
    Outer.Inner in = new Outer().new Inner();
    2. 当内部类在成员位置上,就可以被 成员修饰符 所修饰。
    private :将内部类在外部类中进行封装。
    static :内部类就具备static的特性。
    当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
    在外部其他类中,如何直接访问static内部类的 非静态成员 呢?
    new Outer.Inner().function();
    在外部其他类中,如何直接访问static内部类的 静态成员 呢?
    Outer.Inner.function();


注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。

当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事务在使用外部事物的内容。

  1. 内部类可以被 static 修饰(静态内部类)
     new Outer.Inner().function(); //函数非静态
     Outer.Inner.funtion();//函数静态
  1. 静态内部类才能有静态成员
    当外部类中静态方法访问内部类时,内部类也必须是static
    内部事物在使用外部事物的内容

2)匿名内部类

内部类定义在局部时,
1. 不可被成员修饰符修饰
2. 可直接访问外部类成员,因为还持有外部类中的引用。

但不可以访问他所在的局部变量,只访问被 final修饰 的 局部变量 。
前提:内部类必须 继承 一个类或 实现 接口

new AdvDemo()
{
     void show()
     {
          System.out.println();
     }
}.show();

使用方法:

     new 父类或者接口()
     {
          定义子类内容
     }.方法调用;

其实是一个匿名子类对象,带内容的对象,有点胖。

匿名内部类中定义的方法最好 不要超过3个。

new Object()
{
     void function()
     {
          System.out.println("abc");
     }
}.funtion();

10.异常

1)异常概述

异常 :程序运行时出现的不正常情况。
异常由来:问题也是异常,已被java封装。
java对不正常情况的描述体现。
把问题封装成对象。

划分 严重的问题 非严重的问题
java中 Error类 Exception类
处理 一般不针对代码 可使用针对性处理

Error 和 Exception 都有一些共性内容。

Throwable
|–Error
|–Exception

try
{
     //需要被检测的代码;
}
catch(异常类 变量)
{
     //处理异常的代码(处理方式)
}
finally
{
一定会执行的语句。
}
//Finally代码块只有一种情况不会被执行。就是在之前执行了 System.exit(0) 。

Throwable中的方法

getMessage()
• 获取异常信息,返回字符串。

toString()
• 获取异常类名和异常信息,返回字符串。

printStackTrace()
• 获取异常类名和异常信息,以及异常出现在程序中的位
置。返回值void。

printStackTrace(PrintStream s)
• 通常用该方法将异常内容保存在日志文件中,以便查

2)异常(throws)声明

void fuc() throws Exception{}
要处理才可以通过编译
处理方法:
1. 捕捉 。try{}chatch(Exception e){}finally{}
2. 抛出 。throws

一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常
的一个子集,不能抛出新的异常。

3)多异常处理

1.声明异常时,建议声明更为 具体的异常
throws ArrayException,ArithmeticException

try
{}
catch(ArrayException e)
{}
catch(Exception e)
{}

2.几个异常对应几个catch块
父类catch块放最下面
不定义多余的catch块
3.catch中一定要定义 具体的处理方式
比如异常日志文件

4)自定义异常

class FushuException extends Exception
{
}
//手动抛出
     if(b<0)
          throw new FushuException();

参考JDK、API

继承Exception的原因:
异常类和对象需要被抛出,具备 可抛性 。
这可抛性是Throwable体系中的独有特点。
只有体系中的成员才能被 throws和throw操作 。

5)throw和throws的区别

throws 用在函数上,后跟N个异常类
throw 用在函数内,后跟异常对象

6)RuntimeException

函数内抛出,函数上不声明。
运行时异常
1.若在函数内抛出,函数上不用声明,可编译。
2.若在函数上声明,调用者可不用处理,可编译。

该异常发生,希望程序停止,故有上面现象。

自定义异常,如果该异常发生,无法继续运行运算,
就继承 RuntimeException
异常分类:
1.编译时被检测的异常
2.编译时不检测的异常(运行时异常 RuntimeException)

7)异常-finally

finally中存放的是 一定被执行 的代码
通常用于 关闭资源 。用于数据库连接

分层思想,问题封装

8)异常格式

  1. try-catch
  2. try-catch-finally
  3. try-finally

catch用于处理异常,没catch代表异常没被处理过,需要声明(检测时异常)

9)覆盖时的异常

  1. 子类在覆盖父类时,如果父类方法抛出异常,那么子类的覆盖方法,只能抛出父类异常的异常或者该异常的子类。
  2. 如果父类方法抛出多个异常,子类方法在覆盖父类方法时,只能抛出其子集。也可以自己处理掉异常。
  3. 若父类或接口中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,只能try处理,不能抛。

10)异常总结

是什么?
是对问题的描述,将问题进行对象的封装。
异常体系
Throwable
|–Error
|–Exception

|–RuntimeException

其特点:异常中所有类以及建立对象具备可抛性。
可被throws和throw关键字操作。
throw 定义在函数内,用于抛出异常对象。
throws 定义在函数上,用于抛出异常类,可多个用逗号隔开。

函数内有throw抛出异常对象,并未try处理,必须在函数上throws声明,否则编译失败。但是
RuntimeException除外。
如果函数声明了异常,调用时需要进行处理,可抛可try。
异常有两种:
1. 编译时被检测异常(必须处理)
2. 运行时异常(编译时不检测)

异常处理语句

try
{
//需要检测代码
}
catch(Exception e)//需要处理的异常
{
//处理异常
}
finally
{
     //一定执行的代码。
}

try…catch; try….finally; try….catch….finally

  1. finally中定义的通常是关闭资源的代码
  2. 只有System.exit(0);//系统退出,JVM结束,才不会都finally

自定义异常:
定义类继承Exception或者RuntimeException
1. 为了让该类具有可抛性
2. 让该类具备操作异常的共性方法
可使用父类已经定义好的功能
super(message);
按Java面向对象思想,将程序中出现的特有问题进行封装。

好处:
1. 将问题封装成对象。
2. 将正常流程和处理问题代码分离,方便阅读。

处理原则:
1.try
2.throws
3.抛出几个就处理几个
一个try对应多个catch
4.多个catch,父类异常catch放在最下面
5.catch内需要定义针对性处理方式,一定要写
当捕获到的异常处理不了时,可以继续抛出(可转换成其他异常(相关))

异常注意事项:
在子父类覆盖时:
1. 子类抛出的异常必须是父类异常的子类或者子集。
2. 若父类或接口没抛出异常,则子类只能try

11.包(package)

1)包概述

  1. 对类文件进行分类管理
  2. 给类提供多层命名空间
  3. 写在程序的第一行(代码)
  4. 类名的全程 包名.类名
  5. 包也是一种封装形式。

javac -d . PackageDemo.java
//指定包存放目录
java pack.PackageDemo
java -cp

包与包之间访问,一般要public修饰
protected:仅供子类访问
权限总结:

类型 public protected default private
同一类中 ok ok ok ok
同一包中 ok ok ok
子类 ok ok
不同包中 ok

2)导入(import)

import packa.DemoA;
import packb.*;
若导入的类中有重名,则必须加包名
建议定义包名不要重复,可用url定义
package com.qq.test;

3)jar包

Java压缩包
1. 方便项目携带
2. 方便使用
3. 数据库驱动、框架等都是jar包体现
创建jar包
• jar -cvf mypack.jar packa packb
查看jar包
• jar -tvf mypack.jar [>定向文件]
解压缩
• jar -xvf mypack.jar
自定义jar包的清单文件
• jar –cvfm mypack.jar mf.txt packa packb

c:\ dir>c:\1.txt
native 本地方法

栈、堆、方法区、本地方法区、寄存器

你可能感兴趣的:(02 面向对象)