面向对象
面向对象初识
对于复杂的事物,我们需要从整体、宏观上来进行合理的把控,通过面向对象的思路来分析整个系统。对于其中的一些具体事物,我们需要用到面向过程的思路。
面向对象编程(Object-Oriented Programming,OOP);
面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据;
面向对象的三个特征:
- 封装
- 继承
- 多态
类,对拥有某些相同特征事物进行抽象。对象,某类中的一个具体事物。
构造方法
每一个类都有构造方法,构造方法可以自己定义;
若没有自定义构造方法,类会自带一个无参构造方法;
构造方法的特点:
- 必须和类名相同
- 没有返回类型和返回值
当 new 一个对象时,其本质就是调用构造构造方法,构造方法用来进行属性初始化;
注意点:
- 定义了一个有参构造方法,若想使用无参构造,必须显式定义无参构造;
封装
属性私有,get/set;(private)
封装的好处:
- 增强程序的安全性,保护数据l;
- 隐藏代码的实现细节;
- 统一接口(get/set);
- 增加系统封的可维护性;
继承
extends;
Java中只有单继承,没有多继承,一个父类可以有多个子类,但一个子类只能有一个父类;
子类继承父类中的所有属性和方法(public);
在Java中所有的类都直接或间接继承Object类;
super and this
super 只能在子类的方法或者构造方法中使用,super.方法 表示 调用 父类中的方法。
this 在本类中使用,表示调用的是本类中的属性或者方法。
当new一个子类对象时,会先调用父类的无参构造方法,然后再调用该类的构造方法。
// Student类的无参构造方法
public Studnet(){
super(); // 该行不写默认执行。若显式定义必须放在构造方法的第一行。 表示调用父类的无参构造方法
System.out.println("子类无参构造方法");
}
方法重写
重写的条件:
- 必须有继承关系,子类重写父类的方法;
- 子类重写的方法必须和父类的方法名相同,参数相同;
- 子类重写父类的方法 可以将父类的 修饰符(public protect default private)扩大,但不能缩小;
- 抛出的异常,可以将异常缩小,但不能扩大;
为什么要重写:父类的方法不满足子类的需求;
不能被重写的方法:
- static方法不能被重写,它属于类方法;
- final 常量 不能被重写;
- private 方法不能被重写;
多态
// Studnet类 继承 Person类
public class Studnet extends Person {
}
new Student();
new Person(); //一个对象的实际类型是确定的;
Student s1 = new Student();
Person s2 = new Studnet();
Object s3 = new Studnet(); // 对象的实际类型确定,但是指向的引用类型就不确定:父类的引用可以指向子类。
多态是指方法的多态,主要是看 ( 类名 对象名 = new 子类名() ) 左边的引用类型是什么,和右边的子类关系不大(只要存在继承关系即可)。 父类的引用只能调用父类的方法,子类可以调用本身和继承的方法。若存在方法重写,则都是调用子类重写过后的方法。
instanceof and 子父类型转换
instanceof 用来判断 两个类中是否存在父子关系。
System.out.println(student instanceof Person);// true
子父类型转换:
- 子类向父类转换可以自动转换;
- 父类向子类转换需要强制类型转换;
- 子类向父类转化会丢失一些方法;
static关键字
由static修饰的属性和方法可以通过 类名.属性名或方法名 直接使用。
静态代码块:
{
//匿名代码块;
}
static {
//静态代码块;
}
//构造函数
静态代码块随类的加载而执行,永久只执行一次;
匿名代码块随着对象的创建而执行,每次都会执行;
两者代码块都在构造方法前执行;
由final修饰类不能再被继承,已经断子绝孙;
抽象类
一个类加上abstract修饰符就会变成一个抽象类;
抽象类注意点:
- 抽象类中的方法前加上abstract就会变成抽象方法,抽象方法只有方法名,没有方法体;
- 抽象类中可以有普通的方法;
- 抽象方法必须在抽象类中;
- 不能new抽象类的对象;
若一个类继承了抽象类,则必须重写父抽象类中的所有抽象方法;
接口
接口就是一种约束,和抽象类类似,接口中只能定义抽象方法,比抽象类更加抽象;
定义一个接口使用 interface 关键字; 一个类可以实现多个接口,使用 implements 关键字;
若一个类实现了某个接口,则它必须重写接口中的所有抽象方法;
接口中的方法 默认 有修饰符 public abstract;
接口中也可以属性, 但是 属性必须为 共有 静态 常量;public static final;
接口不能被实例化,没有构造方法;(注意抽象类有抽象方法)
内部类
一个类中可以有多个类,但只能有一个带有public的类;
内部类就是在一个类中在定义一个类;
- 成员内部类
public Outer{
private int age = 10;
public void out(){
System.out.println("外部类方法");
}
public Inter(){
public void in(){
System.out.println("内部类方法"); //成员内部类
}
}
}
//成员内部类实例化 通过 外部类对象.new
Outer outer = new Outer(); //new一个外部类;
Outer.Inter inter = outer.new Inter(); /new 一个外部类;
-
静态内部类
static;
-
局部内部类
方法里面的类;
-
匿名内部类
new Outer.out();
异常机制
Java中把对象当作对象来处理。定义了一个java.long.Throwable作为所有异常的超类;
异常的层次:Throwable->Exception(Error); Throwable 为所有异常超类,Error为错误,Exception为异常;
try,catch,finally,throw,throws
捕获异常
try{
需要处理的以常代码块
}catch(Exception e){
异常处理 //可以捕获多个异常 catch 可以有多个 ,捕获的异常层次需要增加
}finally{ //finally 可选,释放资源居多。
善后工作的处理
}
抛出异常
throw用来主动抛出异常 一般在方法中使用。 若在该方法中无法处理异常,使用throws在方法上向上抛异常;抛出的以上可以捕获;
//假设在方法中,处理不了这个异常。方法上抛出异常
public void ex(int a, int b) throws Exception{
if(b==0) {
throw new Exception();//主动抛出异常,一般在方法中使用;
}
}
//捕获异常
try {
ex(1,0);
}catch(Exception e){
异常处理
}
idea中使用 快捷键 carl + alt + t 生成捕获异常代码