Object-Oriented Programming(oop)
初识面向对象属性+方法=类
面向过程:顺序思考
面向对象:分类的思维模式,先思考如何分类
面向对象的本质以类的方式组织代码,以对象的组织(封装)数据
抽象抽出相像的部分
对象是具体的事务
类是抽象的事物,是对对象的抽象
三大特征
封装
把代码封装起来,留一个口,给别人调用
继承
子类继承父类的所有对象
多态
相同事物会反馈不同的结果
方法的回顾和加深
方法的定义
修饰符
返回值类型:return代表结束方法
方法名
参数列表
异常抛出
方法的调用
静态方法:
静态方法可以在别的类调用 ,static和类一起加载,因此非静态需要实例化
非静态方法形参和实参:
非静态方法需要实例化
值传递和引用传递:
调用方法只传值进去,不改变原来定义的值
引用传递:
本质还是值传递
this关键字:
当前类和对象
对象的创建分析构造器也叫构造方法,是创建对象必须调用的,他有两个特点:
构造器的特点必须和类的名字相同
必须没有返回类型,也不能写void
实例化初始值
一旦定义有参构造,无参构造就必须显示
new的本质就是调用构造器
package day7;
public class Student {
String name;
//无参构造
// public Student(){
// }
public Student(String name) {
this.name = name;
}
public Student() {
}
//有参构造
// public Student(String name){
// this.name=name;
// }
}
默认初始值:
数字 0 0.0
char:u0000
boolean:false
引用:null
面向对象三大特性 封装
该漏的漏,该藏的藏
高内聚,低耦合:
高内聚:就是类的内部数据操作细节自己完成,不允许外部干涉;
低耦合:仅暴露少量的方法给外部使用
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐蔽
属性私有:set/get
调高安全性,保护数据
隐藏代码的实现细节
统一接口
维护性增加了
package day7;
public class Kid {
//属性私有
private String name;
private int age;
private String sex;
private int id;
//set get方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120||age<0){
this.age = 3;
}else{
this.age=age;
}
}
}
继承
extands的意思是“扩展”,子类是父类的扩展
JAVA中只有单继承,没有多继承
继承的本质是对某一批类的继承,实现对现实世界更好的建模
继承是类与类之间的关系
所有的类都继承object类
super
super必须在构造器的第一行,先输出父类的构造器,再子类的构造器
父类的构造器必须在子类构造器的第一行
注意:
super调用父类的构造方法,必须在构造方法的第一个
super必须稚嫩恶搞出现在子类方法或者构造方法的第一个
super和this不能同时调用构造方法
this:
代表的对象不同
this:本身调用者这个方法
super:代表父类对象的应用
前提
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法
this():本类的构造
super():父类的构造
重写
重写都是方法的重写
子类重写父类的方法
方法名必须相同
参数列表必须相同
修饰符:范围可以扩大不能缩小
抛出异常:可以被缩小但不能扩大
重写,子类和父类不许一直,方法体不同
为什么需要重写:
父类的功能,子类不一定需要,或者不一定满足
ALT+INSERT
父类可以指向子类
Student s1 = new Student(); Person p1 = new Student(); Object o1 = new Student(); p1.run();//子类重写了父类的方法,执行子类的方法 s1.run();
子类和父类都有相同的方法,调用父类中的方法时,子类没有重写就调用弗雷德方法,子类重写了父类中的方法就调用子类的方法
对象能执行那些方法,主要看对象左边的类型,和右边关系不大
父类可以指向子类,但是不能调用子类独有的方法
注意
多态是方法的多态
父类和子类有联系,类型转换异常 ClassCastException
存在条件,继承关系,方法需要重写,父类指向子类
(static方法不能重写,属于类,不属于实例,final 常量,private私有)
子类转化为父类,可能会丢失一些方法
多态存在的条件
有继承关系
子类重写父类方法
父类指向子类的对象
多态是方法的多态,属性没有多态
instanceof(类型转换)引用类型
判断两个类之间是否有父子关系
static关键字
package day9;
public class Student extends Person {
{
System.out.println("匿名代码块");
}
static{
System.out.println("静态代码块");
}
public Student() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Student student = new Student();
//先运行静态代码区,再运行匿名代码区,最后运行构造方法
System.out.println("====================");
Student student1 = new Student();
//静态代码块只执行一次
}
}
抽象类和接口
abstract修饰类变成抽象类
package day9;
//接口有多继承,类没有多继承
public abstract class Name {
//约束,有人来实现
//抽象方法,只有方法名,没有方法体
public abstract void doSomeThing();
//1.不能new抽象类,只能通过子类来实现:约束!
//2.抽象类中可以写普通方法
//3.抽象方法必须在抽象类中
//抽象的抽象:约束
public static void main(String[] args) {
}
}
接口
普通类:只有具体的实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范,自己无法写方法,专业的规范!约束和实现分离:面向接口编程
接口就是规范,定义的是一组规则,只需要遵守
作用:
约束
定义一些方法,让不同的人实现
public abstract方法
public static final属性
接口不能被实例化,接口中没有构造方法
implements可以实现多个接口,实现多继承
package day9;
//interface 接口
//类 可以实现接口中 implements 接口
//实现了接口的类,就需要重写接口中的所有方法
//类可以实现多个接口,实现多继承
public interface Characterize {
//接口中的所有定义其实都是抽象的public
//接口中定义常量
//属性
public static final int AGE=99;//属性默认为public static final
//方法
public abstract void run();//方法默认为public abstract
int go();
void date();
int age = 0;
}
内部类及OOP实战
一个java文件只能有一个public class,可以有多个class
package day9;
public class InnerClass {
//内部类
private int id;
public void out() {
System.out.println("这是外部类的方法");
}
public class Inner {
public void in() {
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
public void getId(){
System.out.println(id);
}
}
//局部内部类
public void method(){
class under{
private int age;
public void eat(){
System.out.println("吧唧吧唧");
}
}
}
}
异常
检查性异常
运行时异常
错误
异常处理机制
抛出异常
捕获异常
异常处理的五个关键字
try
catch
finally
package day9;
public class Demo {
public static void main(String[] args) {
int a=1;
int b=0;
try {//监控区域
System.out.println(a/b);
}catch (ArithmeticException e){//遇到异常就执行catch
System.out.println("程序出现异常,b不能为0");
}finally {//处理善后工作
System.out.println("finally");
}
}
}
try,catch一定要,finally可以不要(例如IO流的关闭工作)
捕获多个异常:从小到大捕获
throw
throws
package day9;
public class demo02 {
public static void main(String[] args) {
try {
new demo02().test(1,0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
System.out.println("++++++++");
}
//假设这个方法处理不了这个异常,方法上抛出
public void test(int a,int b) throws ArithmeticException{
if (b==0){
throw new ArithmeticException();//主动抛出异常
}
System.out.println(a/b);
}
}
自定义异常
创建自定义异常类
在方法中通过throw关键字来抛出异常对象
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句来捕获异常并处理;否则在方法声明处用throws关键字来指明抛出给方法调用者的异常,继续进行下一步操作
在出现异常方法的调用者中捕获并处理异常
处理运行时异常是,采用逻辑去合理规避同时辅助try-catch处理
在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
对于不确定的代码,可以加上try-catch,处理潜在的异常
尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
具体如何处理异常,要根据不同的业务需求和异常类型去决定
尽量添加finally语句块去释放占用的资源



