第二十三讲——面向对象(oop)
第二十三讲——面向对象(oop)
1——什么是面向对象
—面向过程 & 面向对象
- 面向过程思想
以类的方式组织代码,以对象的组织(封装)数据。
线型思想,一步一步实施。
适合处理简单问题。
三大特性;
封装 | 继承 | 多态
- 面向对象思想
面对复杂和大型的任务,将任务一一拆解为一个个小任务再拆解直至适合解决任务的思想。最终最底层的的面对思想方法还是要用面向过程来解决。
合适处理复杂的问题,与多人协作的问题。
为了解决复杂的事物,我们要从宏观上把握,从整体上合理分析,我们需要用面对对象的思路来分析整个系统,但是,具体到微观操作,仍然需要面对过程的思路去处理。
—方法调用
方法调用是指在调用其他类或包中类方法所用的方法
package Test;
import Test01.Person01;
public class Application {
public static void main(String[]args){
//同一个package下 调用非静态方法
/**一. 暴力添加static调用
类名.方法名
Person.shout();
二. new方法(本质在调用构造器)
实例化对象,才会使不存在的方法实例化
new 类名();//按atl+Enter
Person person = new Person();
对象名.方法名;
person.shout();
*/
//不一个package下 调用非静态方法
/**
*方法一; 添加static
* 1. import Test01.Person01;—>添加static—>Person01.shout();
* 类名.方法名;
* Person01.shout();
*方法二; new方法
* Person01 person01 = new Person01();
* person01.shout();
* */
}
}
特殊情况
package OOP;
public class Demo01 {
public static void main(String[]args){
//都是静态或非静态才能直接调用
}
//====================================
//static 和类一起加载的
public static void a(){
b();//这里调用了方法b
//然而一个静态的方法调用非静态的方法是会报警出错的
//即一个存在的方法调用了一个不存在的方法
}
//类实例化 之后才存在的
public void b(){
}
}
—形参 &实参
—值传递 & 引用传递
package OOP;
//值传递
public class Demo01 {
//形参 & 实参
public static void main(String[]args){
int i = 0;
System.out.println(i);//0
//Demo01. 加与不加都可以 不知道为什么加 就加吧
Demo01.change(i);
System.out.println(i);//0
//因为java是值传递到最后还是0
}
//返回为空
public static void change(int a ){
a = 10;
}
}
2——类与对象的创建
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但并不能代表具体某一个事物。
- 动物、植物、person、细菌......
- 动物类、植物类、person类、细菌类。用来描述\定义某一种具体事务应该具有的特点和行为
对象是抽象概念的具体实例
- 张三就是person类一个具体实例,张三家里的旺财就是🐕的具体实例
- 能体现出特点,展现出功能的是具体的实例,而不是抽象的概念
创建与初始化对象
一个程序只有一个主启动类(一个main方法);
public class Test23{ //一个程序只有一个主启动类(一个main方法); public static void main(String[]args){ } }
package Base;
public class Base2300 {
//一个程序只有一个主启动类(一个main方法);
public static void main(String[]args){
//抽象的类需要实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例
Student 小明 = new Student();
Student 小红 = new Student();
//同一个类可以有不同的属性
System.out.println(小明.name);//null
System.out.println(小红.age);//0
//使用new关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化 以及对类中构造器的调用
小明.name = "小明";
System.out.println(小明.name);
小明.age = 6;
System.out.println(小明.age);
}
}
package Base;
public class Student {
//一个类中只有属性和方法
//属性
String name;
int age;
//方法
public void study() {
//this指当前的类中的东西
System.out.println(this.name + "在学习");
}
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Base.Base2300
null
0
小明
6
Process finished with exit code 0
3——构造器
构造器叶称为构造方法,是在进行创建对象时候必须调用的
构造器有两个特点;
- 必须和类名字相同
- 必须没有返回类型也不能写void
—构造器的特点
说明一个类即使什么也没写也会存在一个方法
- 构造器的特点
1.与类名称相同
2.没有返回值 也没有void
—构造器的作用
- 使用new关键字 本质是调用构造器
- 用来初始化值
package Test.Test;
//java——>查看class文件
public class Person {
//1.与类名称相同
//2.没有返回值 也没有void
String name;
//1.使用new关键字 本质是调用构造器
//2.用来初始化值
//()无参数 无参构造
//一旦定义了无参构造 无参必须显示定义
public Person(){//重载
this.name = "小次郎";
}
//()有参数 有参构造
public Person(String name){
this.name = name;
}
}
/**
* package Test.Test;
*
* public class Application {
* //一个程序应该只有一个主方法(main)
* public static void main(String[]args){
* //new 实例化了一个对象
* Person person = new Person();
* //()为null所以调用无参构造 小次郎
* System.out.println(person.name);
* Person person1 = new Person("大聪明");
* System.out.println(person1.name);
* }
* }
*
* 构造器特点;
* 1.和类名相同
* 2.没有返回值 没有void
* 作用;
* 1.new 本质在调用构造方法
* 2.初始化对象的值
* 注意点;
* 1.定义有参构造后,必须写入参数 ,否则,必须添加无参构造器
* 快捷键;
* alt+insert 添加构造方法
*
*/
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.Test.Application
小次郎
大聪明
Process finished with exit code 0
—alt+insert快捷键
package Test.Test;
public class Person {
//===alt+insert 快捷键===
// 属性
String name;
int age;
//方法 按alt+insert 快捷键生成
//选择 SelectNone
public Person() {
}
//选择OK
public Person(String name) {
this.name = name;
}
//按住Ctrl 选择两个参数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
/**
* package Test.Test;
*
* public class Application {
* //一个程序应该只有一个主方法(main)
* public static void main(String[]args){
* //new 实例化了一个对象
* Person 晓忠 = new Person("晓忠");
* System.out.println(晓忠.name);
* Person person = new Person();
* System.out.println(person.name);
* Person person1 = new Person("小红",12);
* System.out.println(person1.age);
* }
* }
* =============================================
*
*C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.Test.Application
* 晓忠
* null
* 12
*
* Process finished with exit code 0
*/
4——对象和类小结
/**
* 1. 对象与类
* 类是一个模板——抽象 对象是具体的实例——具体
* 2. 方法
* 定义、调用
* 3. 对象的引用
* 引用类型; 基本类型(8)整数型 浮点数 字符型 boolean
* 对象是从引用来操作的; 栈---->堆
* 4. 属性; 成员temp
* 默认初始化;
* data; 0 0.0
* char; u0000
* boolean; false
* 引用; null
* 修饰符; 属性类型 属性名 = 属性值
* 5. 对象的创建和使用
* - 必须使用new 关键字 创造对象, 构造器 Person 校花 = new person();
* - 对象的属性 校花.name;
* - 对象的方法 校花.sleep();
* 6. 类;
* 属性
* 方法
* */
5——封装(数据的隐藏)
**高内聚; 类的内部数据操作由自己完成,不允许外部干涉 **
低耦合; 仅暴露少量的方法给外部使用
就是将代码藏起来,给Users使用统一接口来访问。
属性私有,get/set
package Test;
public class Application{
public static void main(String[]args){
Person s1 = new Person();
//s1.name = 12;不是public 是private所以不能赋值 报错
s1.getName("晓忠");
System.out.println(s1.setName());
//==================================
//设置年龄越限问题
s1.setAge(999);
System.out.println(s1.getAge());
/**
* 1. 提高程序的安全性,保护数据
* 2. 隐藏代码的实现细节
* 3. 统一接口
* 4. 系统可维护增加
* */
}
}
package Test;
public class Person{
//public 公共的 private 私有的
//属性
private String name; // 名字
private int id; // 学号
private char sex; // sex
private int age;
//方法
//提供一些可以操作属性的方法
//提供一些public 的 get set方法
//get 获取这个数据
public String setName(){
return this.name;
}
public void getName(String name){
this.name = name;
}
//alt + insert 选择get+set可以生成方法
public int getAge() {
return age;
}
//可以约束数据 规范数据
public void setAge(int age) {
if(age>120 || age<0){
this.age = 3;
} else{
this.age = age;
}
}
}
- 用private来,设置属性
- 用 get/set 来获取和输入数据
- 以及set数据的规范
6——继承(extends)
类是一批对象的抽象; 而继承是一批类的抽象
子类继承了父类,就会拥有父类的全部方法
JAVA中只有单继承,没有多继承,一个类只有一个父类,可以有多个子类
类与类的关系有;
继承
组合
聚合等等、、、
—继承的使用
- 格式
public class Student extends Person{
//子类 extends 父类
}
/**
作用
— 可以继承父类的所有方法
*/
—Extends 中的 Public and Private
public; 公共的
private; 私有的
-
名字是private 是私有的不允许自接被继承 需要添加 get set方法来操作
/* 拓展修饰符 -public 最高级 -protected 受保护的 -default 默认的 | 不符合的 -private 私有的 */
-
extends的get and set
—extends 三大重点
extends 三大重点
- Object
- super
- 方法重写
Object
public class Persoon /*extends Object*/ //在JAVA中,所有的类,都默认直接或间接继承Object
Super
—调用父类—属性
—调用父类—方法
—super 特性
Super注意点:
- super 调用父类的构造方法,必须在构造方法的第一个
- super 必须只能出现在子类的方法或构造方法中
- super 和 this 不能同时调用构造方法
Vs this:
this; 本身掉调用者这个对象
super; 代表父类对象的应用
前提;
this; 没用继承也可以使用
super; 只能在继承条件才可以使用构造方法
this(); 本来的构造
super(); 父类的构造
方法重写
重写是指方法的重写与属性无关
只有非静态才有重写!!!
子类重写了父类的方法,执行子类的方法
非静态重写
静态
静态小结;
//A子类 B父类
A a = new A();
//======
B a = new A();
-
静态方法;方法的调用只和左边,定义的数据类型有关
-
静态方法;父类的引用可以指向子类
B b= new A();
-
重写是指方法的重写,与属性无关
/**
* 重写; 需要继承关系,字类重写父类的方法
* 1. 方法名必须 相同
* 2. 参数列表必须相同
* 3. 修饰符; 范围可以扩大但不能缩小: public>Protected>Default>private
* 4. 抛出的异常: 范围。可以被缩小,不能扩大; ClassNotFoundException/找不到类-->Exception(大)
*
* 重写: 子类与父类的方法必须一致,方法体不同!!
*
* 为什么需要重写; 父类的功能,子类不一定需要,或者不一定满足
*
* 快捷键Atl+insert 选择 Override
* */
7——多态
-
多态编辑: 类型:可拓展性
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类 | 相关类)
-
多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
-
和重写一样,属性没有多态性
-
只有父类和子类 有联系的才有多态, 要防止转换异常 ClassCastException
- static 方法,属于类 不属于实例 所以不能做重写
- final 常量 在常量池里 也不许做重写
- private 私有的不能做重写
8——instanceof和类型转换
instanceof
/**
* instanceof : 判断类型是否存在父子关系
* true: 存在父子关系
* false: 有关系 不是父子关系
* 报错: 引用类型同级报错 || 其他报错
* */
package Test.demo08;
//Teacher类与Student类继承Person
public class Application {
/**
* instanceof : 判断类型是否存在父子关系
* true: 存在父子关系
* false: 有关系 不是父子关系
* 报错: 引用类型同级报错 || 其他报错
* */
public static void main(String[]args){
Object object = new Student();
//Object > Person > Student
//Object > Person > Teacher
System.out.println("===object==========================");
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("===person==========================");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String); //引用类型同级报错
System.out.println("===student==========================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher); // 引用类型同级报错
//System.out.println(student instanceof String); // 其他报错
}
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo08.Application
===object==========================
true
true
true
false
false
===person==========================
true
true
true
false
===student==========================
true
true
true
Process finished with exit code 0
类型转换
package Test.demo09;
public class Application {
public static void main(String[]args){
//====类型转换===== 父<———>子 高<———>低
Student s1 = new Student();
s1.go();//子类的go
s1.run();//父类的run
//===================================
//==================================
Person p1 = new Student();//父类的引用指向子类
/**
* 父类———不能直接调用———>子类
* p1.go();//false 需要将Person这个对象转换为Student类型,就能使用Student的方法了
* 高————>低 需要强制转换
* */
System.out.println("===高——>低==父——>子====================");
((Student)p1).go();
p1.run();
}
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo09.Application
go
run
===高——>低==父——>子====================
go
run
Process finished with exit code 0
子类转换成父类可能会丢失一些自己本来的方法
9——Static关键字详解
- static 在类中使用是修饰成员变量
- 加在方法上是静态方法
- 加在属性上是静态属性
—关于属性
package Test01;
public class Student {
private static int age;//静态变量 需要很多类用到的话用static
private double score;//非静态变量
public static void main(String[] args) {
System.out.println(Student.age);//直接调用的 static可以直接调用
/** 使用 类名.属性名
以便知道是静态属性。*/
System.out.println(age);
//========非静态 new方法==============
Student s1 = new Student();
System.out.println(s1.age);//依据对象实例化后调用的
System.out.println(s1.score);//依据对象实例化后调用的
}
}
—关于方法
package Test01;
public class Test01 {
public void go(){
//非静态方法可以调用静态方法所有东西 非静态和类一起加载出来
}
public static void run(){
//静态方法不能直接调用非静态方法 因为非静态和类一起加载 加载出来前都没有静态方法
//静态方法可以调用静态方法
}
public static void main(String[]args){
Test01.run();
run();//静态方法可以直接调用
//非静态调用
new Test01().go();//新的调用格式
Test01 t1 = new Test01();
t1.go();
}
}
—关于代码块
package Test01;
public class Demo01 {
{ /***
——代码块(匿名代码块)——
没有名字的代码块程序并不能主动的调用这个模块
创建对象的时候就创建了
在构造器之前
*/
System.out.println("匿名代码块启动");
//——作用赋予初始值
}
static {
/**
* ————静态代码块 ————
* 类一加载就直接执行
* 永久只执行一次
* */
System.out.println("静态代码块启动");
}
public Demo01() {
System.out.println("构造器启动");
}
public static void main(String[]args){
Demo01 d1 = new Demo01();
System.out.println("====分割线=============");
Demo01 d2 = new Demo01();
}
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test01.Demo01
静态代码块启动
匿名代码块启动
构造器启动
====分割线=============
匿名代码块启动
构造器启动
Process finished with exit code 0
package Test01;
//导入 Math具体方法就不用加Math
//import static java.lang.Math.random;
import static java.lang.Math.*;
public class Test02 {
public static void main(String[]args){
System.out.println(random());//会产生一个随机数
System.out.println(PI);
//Math.PI
}
/**
* 关注官方文档就有好多玩法
* */
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test01.Test02
0.615037571204595
3.141592653589793
Process finished with exit code 0
10——abstract/抽象类
-
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类那么该类就是抽象类。
-
抽象类中可以没有抽象方法,到那时有抽象方法中类一定要声明为抽象类
-
抽象类,不能使用new关键字来创建对象,它是用来子类继承的
-
抽象方法,只有方法的声明没有方法的实现,它是用来让子类实现的
-
子类继承抽象类那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
11——接口
功能对比;
- 普通类: 只有具体实现
- 抽象类: 具体实现和规范(抽象方法)都有!
- 接口 : 只有规范! 自己无法写方法!
什么是接口;
接口就是规范,定义了一组规则,体现显示世界中 “如果是,则必须” 的思想。
接口的本质是契约,和法律也要,制定后需要去遵守
OO(面向对象)的精髓是,是对对象的抽象,最能体现这一点的是接口。
package Test.demo11;
//
//利用接口实现 多继承
public class UserServiceImpl implements UserService,TimeService{
//实现接口 需要重写方法 不然会报红 | 实现类公式 implements 接口名称
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
/**
* package Test.demo11;
*
* public interface TimeService {
* void timer();
* }
* */
package Test.demo11;
//calls类 换成interface 接口
public interface UserService {
//在接口定义的属性都是常量 final
//public static final | int age = 99;
public static final int age = 99;
void add (String name);
void delete(String name);
void update(String name);
void query (String name);
}
/**
* -接口不能写方法
* -接口中所有定义其实都是默认抽象的
* public abstract 自己写会标灰
* -{public abstract void add(String name)| void add (String name)}
* -接口需要实现类———UserServiceImpl
* */
作用;
- 约束
- 定义一些方法,让不同的人实现~ 10 ---1有一个任务多种不同的实现方式
- public abstract
- public static final
- 接口不能实例化(new)~ 接口中没有构造方法
- implments 可以实现多个接口
- 必须重写接口中的方法
12——N种内部类
-
内部类就是在一个类的内部再定义一个类,比如在A类中定义一个B类,那么B类就是A类的内部类,而A类就是B类的外部类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
—成员内部类
package Test.demo12;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类来实例化内部类
//outer.new Inner(); 外部类对象名. new 内部类名();
Outer.Inner inner = outer.new Inner();
//内部类可以调用外部类的私有属性与方法
inner.in();
inner.getId();
inner.getOut();
}
}
//===============成员内部类===============================
package Test.demo12;
//Outer : 外部类
public class Outer {
private int id = 729;
public void out(){
System.out.println("这是外部类的方法");
}
//Inner : 内部类
class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
public void getId(){
System.out.println(id);
}
public void getOut(){
out();
}
}
}
显示
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo12.Application
这是内部类的方法
729
这是外部类的方法
Process finished with exit code 0
加static 就变成静态内部类
—局部内部类
package Test.demo13;
public class Outer {
//局部内部类
public void method(){
class Inner{
public void in(){
}
}
}
}
—匿名内部类
package Test.demo13;
//匿名内部类
public class Test {
public static void main(String[] args) {
/**
* Apple apple = new Apple();
* 实例化了Apple类并赋值给对象apple 对象名是apple
* apple.eat();
* */
//匿名内部类 匿名对象的使用 这个对象没有名字
//不用将实例保存到变量中
new Apple().eat();
new UserService(){
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("Apple 12 Max Pro");
}
}
interface UserService{
void hello();
}
C:\Users\夏天的风\Desktop\DEMO-XXZ\out\production\DEMO-XXZ Test.demo13.Test
Apple 12 Max Pro
Process finished with exit code 0
—测试类
package Test.demo13;
public class Outer {
}
//Java类中只有一个public class类 但是可以有多个class类
//写测试类方便
class A{
public static void main(String[] args) {
}
}
新增单词
1 | change | 改变 | 劝G~ | |
---|---|---|---|---|
2 | person | 人类 | 佩尔森~ | |
3 | Application | 应用 | 啊婆利K xun~ | |
4 | insert | 插入 | in射te~ | |
5 | Select | 选择 | 塞阿克特~ | |
6 | None | 一个也不;什么也不 | 诺内 | |
7 | SelectNone | 一个也不选择 | 塞阿克特诺内 | 一个选项 |
8 | cancel | 取消 | 康塞尔~ | 一个选项 |
9 | sleep | 睡觉 | 斯利普 | |
10 | private | 私有的 | 怕维特~ | |
11 | sex | 性别 | 傻克斯~ | |
12 | get | 获取 | 给他~ | |
13 | set | 设置 | 塞特~ | |
14 | say | 说话 | 塞伊~ | |
15 | shout | 吼叫 | 笑T~ | .sout | 输入快捷方式区分开来 |
16 | extends | 继承 | E克斯蛋丝~ | |
17 | refactor | 重构 | 确认 | 瑞发可特~ | 可以 和doctor 一起记 |
18 | teacher | 教师 | ti却~ | tea茶 char字符 |
19 | Object | 对象 | 熬不掘KT~ | 所有的类都继承Object |
20 | super | 超级 | 特级 | 指父类 | 联系superMan | |
21 | Override | 重写 | 偶夫掳爱的~ | Over+ride记 |
22 | instanceof | 判断关系类型 | 因丝等次of~ | (Student—instanceof —Person)是否有父子关系 |
23 | Math.random() | 产生随机数 | 乱蹬~ | Math.random() |
24 | abstract | 抽象的 | 啊不丝架可T~ | |
25 | dosomething | 做某些事 | do 桑 婶~ | |
26 | interface | 接口 | 英特尔face | intel 英特尔 | face脸 |
27 | UserService | 用户服务 | User瑟维斯~ | |
28 | add | 增 | a的~ | 增删改查 |
29 | delete | 删 | ||
30 | update | 改 | up戴特~ | date 日期 |
31 | query | 查 | kwei瑞~ | very 非常 | query 查 |
32 | implements | 实现 | 英噗门次~ | impl | 实现 缩写 |
33 | Outer | 外部类 | 外在的 | 凹特儿~ | |
34 | Inner | 内部类 | 内在的 | in 纳~ |