面向对象
面向对象oop本质:以类的方式组织代码,以对象的形式(封装)数据
1.抽象:抽像(抽离出来相像的东西)
2.三大特性:封装,继承,,多态
从认识论角度考虑先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
从代码运行角度考虑是先有类后有对象。类是对象的模板。
面向过程是具体的,面向对象是抽象的。
方法
方法的定义
-
修饰符
-
返回类型
*break:跳出switch,结束循环和return的区别*
-
方法名:注意规范 首字母小写加驼峰命名
-
参数列表:(参数类型,参数名)…
-
return
-
异常抛出
方法的调用
- static:直接 类名.方法名
非static:先实例化这个类 new {类名 对象名 = new 构造方法();===(对象类型 对象名 = 对象值)}
- 形参和实参
- 值传递和引用传递(回头看62集)
- this关键字
** 类里面只有:属性和方法**
使用new关键字创造对象:
使用new关键字创建的时候,除了分配内存空间外,还会给 创建好的对象 进行默认的初始化 及对类中构造器的调用。
构造方法(构造器)
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有一下俩特点:
- 必须和类的名字相同
- 必须没有返回类型,不能写void。
一个类即使什么也不写,他也会存在一个方法(和类同名的无参构造方法)
package com.oop.Demo02;
public class person {
String name;
int age;
public person() {//如果定义了有参构造方法,无参构造方法就必须显现出来
}
public person(String name) {
this.name = name;
}
//1.使用new 本质是在调用构造器
//2.构造器用来对 对象 进行初始化
public person(String name, int age) {
this.name/*当前类的*/ = name/*参数传进来的值*/;
this.age = age;
}
}
/* 测试方法 (对象类型 对象名 = 对象值)
* public static void main(String[] args) {
//实例化了一个对象 类名 对象名 = new 构造方法();
person ning = new person();//调用无参构造方法
System.out.println(ning.name);
System.out.println("=====================================");
person zhao = new person("wst",34);//调用有参构造方法
System.out.println(zhao.name+"\n"+zhao.age);
}
结果:
* null
=====================================
wst
34
总结:
构造器:
特点:
1.和类名相同
2.没有返回值
作用:
1.使用new 本质是在调用构造器(构造方法)
2.来对 对象 进行初始化
注意:定义有参构造后,想调用无参构造,必须显示定义无参构造方法出来
Alt+Insert 生成构造器
this.name(当前类的name) = name;(参数传进来的值)
* */
person ning = new person(); 这一行会先跑:1.静态代码块(如果有)2.匿名代码块(如果有)3.构造方法(肯定有)【在构造方法中输出提示可以看出来】
封装
特点:private属性私有,public (get、set)
package com.oop.Demo04;
public class student {
//加入私有变量private之后,主方法不能调用(student1.name)这个属性了
//属性私有化
private String name;
private int age;
private char sex;
//不能 直接对象名.属性 调用那就要get、set 方法
/*自己写的get和set方法,易错点:set需参不需返为void(设置好 在这交给get去 返 就行了) get是(得到)return回去才能得到,get可要this也不要,意义一样*/
// public String setName(String name){
// return this.name=name;
// }
// public String getName(){
// return this.name;
// }
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
if(age<0||age>110){
this.age=3; //意外收获:在方法中,(this.age)是一个整体指这个类里的age
} else //而单个出现的age 都是指外部传入参数的age
this.age=age;
}
public int getAge(){
return age;
}
public void setSex(char sex){
this.sex=sex;
}
public char getSex(){
return sex;
}
}
/*测试方法
public class Application {
public static void main(String[] args) {
student student1 = new student();
student1.setName("wsix");
student1.setAge(13);
System.out.println(student1.getName());
System.out.println(student1.getAge());
student student2 = new student();
student2.setName("kuang");
student2.setAge(22);
student2.setSex('男');
System.out.println(student2.getName());
System.out.println(student2.getAge());
System.out.println(student2.getSex());
}
}*/
封装的意义:Alt+Insert (getter and setter)
- 提高了程序的安全性,保护数据
- 隐藏了代码的实现细节
- 统一了接口
- 系统可维护增加了
继承
extends ”扩展“。
只支持单继承 Ctrl+H 打开右侧的Hierarchy(继承关系树)
super:只能在子类使用 用来调用父类中 非private修饰的属性和方法(子类重载了父类的属性和方法但是可通过super来调用父类的属性和方法)
关于super的细节:主方法 中 Student student1 = new Student(); 即调用Student的构造方法时,先跳到Student的父类构造方法,才回跳到子类Student的构造方法(相当于子类的构造方法有一个隐藏的super();用来调父类的构造方法),且子类的构造方法必须与父类一致(有参或无参)
super注意点:
1.super调用父类的构造方法,必须在构造方法中的第一个;
2.super只能出现在子类或者父类的构造方法中!
3.super和this不能同时调用构造方法!
this与super的区别
代表的对象不同:this:本身调用者这个对象
super:代表父类对象的应用
前提:this:没有继承也可以使用
super:只有在继承条件才能使用
构造方法:this();本类的构造
super(); 父类的构造
方法重写
重写和重载两个不同的概念:重写是子类重写父类方法,重载只是(同一类中)参数个数或者类型不同
重写:需要继承关系,子类重写父类的方法!(重写是方法的重写和属性无关)
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以扩大,不能缩小(public>protected>default>private)
4.抛出的异常:范围可以缩小,不能扩大ClassNotFoundException–>Exception(大)
重点:子类的方法和父类必须一致,方法体不同!
重写意义:父类的功能子类不一定喜欢 Alt +Insert: override
重写了的方法在左边有标志 子O↑ 父O↓
多态
即同一方法可以根据发送对象的不同而采取多种不同的行为方式。
一个对象的实际类型是确定的,可以指向的引用类型就不确定。(Father s2 = new Son(); 这里指向Father这个引用类型)
Son s1 = new Son();
//父类的引用指向子类 左边还可以Object类
Father s2 = new Son();//s2这个对象是Father类型的,点不出子类独有的方法,但能通过强转弄出来子类的方法
/* 高 低
Person s2 = new Student();
Student s2a = (Student) s2;
s2a.(子类方法) Person对象s2就可以用子类方法了
*/
s1.run();
s2.run();//子类重写了父类的方法则执行子类的,否则执行父类的
//对象执行哪些方法主要看对象左边的类型,和右边关系不大
多态存在条件(多态是方法的多态,属性没有多态性)
有继承关系方法,子类重写父类,父类引用指向子类对象 Father s2 = new Son();
instanceof
强制转换高转低可能会丢失精度
多态总结:
1.父类引用指向子类对象[(Person s2 = new Student())s2的引用类型是Penson]
2.把子类转换为父类,向上转型
3.把父类转换为子类,向下强制转换
4.方便方法的调用,减少重复的代码
抽象:封装,继承,多态。核心编程思想abstract抽象
修饰符补充
static静态修饰的 (东西) 是跟类一起加载出来的,可以直接类名.(东西)用,其他的跟对象加载,有对象才有其他
final修饰的类是断子绝孙的,不能被继承。
抽象类
-
abstract修饰的类抽象类,里面有abstract修饰的抽象方法,只有方法名字不用写方法的实现 public abstract viod add(); (这是一个规范) (不需要{}来写方法主体了)
-
抽象类的所有方法,继承了他的子类必须重新抽象类的方法,除非 子类也有abstract修饰,那就子子类重写。
-
抽象类可以有普通方法,抽象方法必须在抽象类中。
抽象类特点:不能new 出来(不能实例化),只能由子类来实现它才能用,子类实现它必须重写它方法;它是约束
抽象类存在的意义
比如本科和研究生可以抽象成学生,他们有相同的属性和方法。这样当你对其中某个类进行修改时会受到父类的限制,这样就会提醒开发人员有些东西不能进行随意修改,这样可以对比较重要的东西进行统一的限制,也算是一种保护,对维护会有很大的帮助。
接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有!
- 接口:只有规范!没有body。无法自己写方法专业的约束!约束和实现分离:面向接口编程(定义方法的约束,通过实现类来实现它)
接口:
package com.oop.Demo08;
//定义 class改为interface
public interface UserService {
// 接口里所有定义都是抽象的public abstract 默认给你加这句话
void add();
void delete();
void updata();
void query();
}
接口的实现类: (接口的实现类 implement实现接口,实现类必须重写接口的方法)
package com.oop.Demo08;
//接口的实现类 implement实现接口,实现类必须重写接口的方法
public class UserServiceImpl implements UserService,TimeService{
@Override
public void add() {
}
@Override
public void delete() {
}
@Override
public void updata() {
}
@Override
public void query() {
}
@Override
public void timer() {
}
}
接口的本质是契约:就像法律一样,制定好大家都要遵守。
oo的精髓,是对 对象的抽象,最能体现这一点的就是接口。
接口的作用
-
约束
-
定义方法让不同的然实现
-
(public abstract) 返回类型 方法 例: void add();
-
(public static abstract) 属性
-
接口不能被实例化,new不出来,接口中没有构造方法
-
implements可以实现多个接口,实现类必须重写接口的方法
匿名内部类:new A().test(); 相比于 A a = new A(); 前者是匿名内部类不需要把new 出来的对象赋值给某个值,可以直接点出来它的方法。后者把new出来的对象赋值给了a。
Exception 异常
Error类由java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。jvm会选择线程终止。
Exception: 有一个重要的子类分支RuntimeException(运行时异常)
这些异常是不检查异常,程序可以选择捕获也可以不处理。
Error和Exception区别,Error由java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。jvm会选择线程终止。Exception通常是可以被程序出来的,并且在程序中尽可能的去处理这些异常。
抛出异常 捕获异常
关键字try、catch、finally、throw、throws
public static void main(String[] args) {
int a=1;
int b=0;
try {//try监控区域
System.out.println(a/ b);
} catch (Exception e) {//catch 想要捕获的异常类型,有就输出{}的内容
System.out.println("异常");
e.printStackTrace();//打印堆栈跟踪
}
finally {//善后工作
System.out.println("不管有无我都输出");
}
}
throw、throws不同点:(throw制造异常,throws抛出异常)
自定义异常 继承Exception类:
package com.Exception.demo02myex;
//自定义异常
public class MyException extends Exception {
private int detail;
public MyException( int detail) {
this.detail = detail;
}
//toString
@Override
public String toString() {
return "MyException{" +
"detail等于" + detail +
'}';
}
}
package com.Exception.demo02myex;
public class Test {
//可能会存在异常的方法
static void test(int a) throws MyException{
if(a>10){
throw new MyException(a);
}else
System.out.println("OK");
}
public static void main(String[] args) {
try {
test(33);
} catch (MyException e) {
// e.printStackTrace();
System.out.println(e);
}
}
}
//输出MyException{detail等于33}