一、面向对象和面向过程的关系
1)面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做;
2)面向对象:强调了具备功能的对象,以类/对象为最小单位,考虑谁来做。
总结一手:
不管是面向过程、面向对象,都是程序设计的思路。
二、Java类/类成员
1-概述
2-类和对象的关系
3-对象的创建与使用
4-对象的内存解析
5-类的成员之一属性(成员变量field)
6-类的成员之二:方法(method)
public class Person {private String name; // 字符串类型的 name 属性private int age; // 整数类型的 age 属性// get 方法用于获取 name 属性值public String getName() {return name;}// set 方法用于设置 name 属性值public void setName(String name) {this.name = name;}// get 方法用于获取 age 属性值public int getAge() {return age;}// set 方法用于设置 age 属性值public void setAge(int age) {this.age = age;}
}
public class Test {public void show(int i) {System.out.println("show(int)");}public void show(String s) {System.out.println("show(String)");}public void show(String... strs) {System.out.println("show(String...)");for (int i = 0; i < strs.length; i++) {System.out.println(strs[i]); // 遍历可变参数数组}}public static void main(String[] args) {Test test = new Test();test.show(5);test.show("hello");test.show("hello", "world");test.show();test.show(new String[]{"AA", "BB", "CC"});}
}
7-类的成员之三:构造器
8-类的成员之四:代码块
9-类的成员之五-内部类
成员内部类(静态/非静态)
局部内部类
匿名内部类
10-Java Bean
11-Java UML
1)什么是UML?
1、UML(统一建模语言),是一种用于软件系统分析和设计的语言工具,用于帮助软件开发人员进行思考和记录思路的结果。
2、UML本身是一套符号的规定,就像数学符号和化学符号一样,这些符号用于描述软件模型中的各个元素和它们之间的关系,如类、接口、实现、泛化、依赖、组合、聚合等。
2)UML的分类
1、用例图
2、静态结构图:类图、对象图、包图、组件图、部署图。
3、动态行为图:交互图(时序图与协作图)、状态图、活动图。
类图:描述类与类之间的关系,是UML图的核心。
3)UML 类图
1、用于描述类(对象)本身的组成和类(对象)之间的各种静态关系。
2、类之间的关系:依赖、泛化(继承)、实现、关联、聚合、组合。
类图示例代码
public class Person {private Integer id;private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
(1)依赖关系
只要在类中用到对方,它们之间就会存在依赖关系。
public class PersonServiceBean {private PersonDao personDao;public void save(Person person) {}public IDCard getIDCard(Integer personid){return null;}public void modify(){Department department = new Department();}
}public class IDCard {
}public class Department {
}public class Person {
}public class PersonDao {
}
(2)泛化关系
泛化关系就是继承关系,是依赖关系的特例。
public abstract class DaoSupport {public void save(Object entity){}public void delete(Object id){}
}public class PersonServiceBean extends DaoSupport {
}
(3)实现关系
实现关系就是一个接口被一个类实现了,是依赖关系的特例。
public interface PersonService {public void delete(Integer id);
}public class PersonServiceBean implements PersonService {@Overridepublic void delete(Integer id) {}
}
(4)关联关系
1、关联关系等同于类与类之间的联系,是依赖关系的特例。
2、关联具有导航性:就是双向关系和单向关系。
3、关联具有多重性
单向一对一关系:
public class IDCard {
}public class Person {private IDCard idCard;
}
(5)聚合关系
聚合关系表示整体和部分的关系,整体与部分可以分开。聚合关系是关联关系的特例,同样具有导航性和多重性。
public class Computer {private Mouse mouse;private Moniter moniter;public void setMouse(Mouse mouse) {this.mouse = mouse;}public void setMoniter(Moniter moniter) {this.moniter = moniter;}
}public class Moniter {
}public class Mouse {
}
(6)组合关系
整体与部分的关系,但是整体与部分不可以分开。
public class Computer {private Mouse mouse = new Mouse();private Moniter moniter = new Moniter();public void setMouse(Mouse mouse) {this.mouse = mouse;}public void setMoniter(Moniter moniter) {this.moniter = moniter;}
}
三、面向对象的三大特征
前置补充:要用到的关键字
2.特点
被static修饰的成员随着类的加载而加载
被static修饰的成员由于跟着类到内存,所以优先于对象存在
被static修饰的成员属于子类成员,不属于对象成员(成员方法,成员变量)
根据static所在的类创建出来的对象,都会共享这个静态成员
3.使用
修饰成员变量 :static 数据类型 变量名
修饰方法:
修饰符 static 返回值类型 方法名(参数){
方法体
return 结果
}
4.使用:
特性1-封装性
1)空参构造
2)权限修饰符
3)有参构造
特性2-继承性
补充:抽象
package com.atguigu.b_abstract;public abstract class Employee {private String name; // 员工姓名private int age; // 员工年龄public Employee() {}public Employee(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}/*** 员工工作的抽象方法*/public abstract void work();// public abstract void eat();
}
package com.atguigu.b_abstract;public class Teacher extends Employee{public Teacher() {}public Teacher(String name, int age) {super(name, age);}@Overridepublic void work() {System.out.println("讲师在讲课");}}
package com.atguigu.b_abstract;public class Test {public static void main(String[] args) {Teacher t1 = new Teacher("涛哥", 16);t1.work();}
}
补充:接口
怎么定义接口 ?
package com.atguigu.d_interface;public interface USB {public abstract void open();abstract void close();public default void sleep(){System.out.println("USB休眠");}
}
package com.atguigu.d_interface;public class Mouse implements USB{@Overridepublic void open() {System.out.println("鼠标开启");}@Overridepublic void close() {System.out.println("鼠标关闭");}
}
package com.atguigu.d_interface;public class Test01 {public static void main(String[] args) {Mouse mouse = new Mouse();//接口不能直接new对象mouse.open();mouse.close();}}
【默认方法:】
package com.atguigu.e_interface;public class Mouse implements USB{@Overridepublic void methodDef(){System.out.println("我是重写的接口中的默认方法");}
}
package com.atguigu.e_interface;public interface USB {//默认方法public default void methodDef(){System.out.println("我是接口中的默认方法");}//静态方法public static void methodSta(){System.out.println("我是接口中的静态方法");}
}
package com.atguigu.e_interface;public class Test01 {public static void main(String[] args) {Mouse mouse = new Mouse();mouse.methodDef();System.out.println("================");USB.methodSta();}
}
静态方法:
【接口:成员方法】
特性3-多态性
1)基本概念
package com.atguigu.h_duotai;
/**父类**/
public class Animal {public void eat(){System.out.println("动物要吃饭");}
}package com.atguigu.h_duotai;
/**子类1**/
public class Dog extends Animal{/**有子类继承关系有方法重写**/public void eat(){System.out.println("狗啃骨头");}//特有方法public void lookDoor(){System.out.println("狗会看门");}
}package com.atguigu.h_duotai;
/** 子类2**/
public class Cat extends Animal{/**有子类继承关系有方法重写**/@Overridepublic void eat() {System.out.println("猫吃鱼");}//特有方法public void catchMouse(){System.out.println("猫会抓老鼠");}
}package com.atguigu.h_duotai;
/**测试类**/
public class Test01 {public static void main(String[] args) {//原始方式new对象Dog dog = new Dog();dog.eat();dog.lookDoor();System.out.println("==========");Cat cat = new Cat();cat.eat();cat.catchMouse();System.out.println("=====以下是多态形式new=====");//多态形式new对象Animal animal = new Dog();animal.eat();//animal.lookDoor();//多态前提下,不能直接调用子类特有功能//lookDoor是子类特有方法,不能直接调用,下述一样System.out.println("=======");Animal animal1 = new Cat();animal1.eat();//animal1.catchMouse();//多态前提下,不能直接调用子类特有功能}
}
2)多态成员以及成员方法的访问特点
package com.atguigu.i_duotai;
public class Fu {int num = 100;public void method(){System.out.println("父类中的method方法");}
}package com.atguigu.i_duotai;
public class Zi extends Fu{int num = 10;public void method(){System.out.println("子类中的method方法");}
}
package com.atguigu.i_duotai;
/****/
public class Test {public static void main(String[] args) {//多态方式new一个对象Fu fu = new Zi();//成员变量没有多态性,成员方法要是有重名的直接子类重写就行了System.out.println(fu.num);//父类的100fu.method();System.out.println("============");//原始方式Zi zi = new Zi();System.out.println(zi.num);//子类的10zi.method();}
}输出:
100
子类中的method方法
============
10
子类中的method方法
3)多态的好处
4)多态的转型
package com.atguigu.k_duotai;public class Test01 {public static void main(String[] args) {Dog dog = new Dog();method(dog);Cat cat = new Cat();method(cat);}public static void method(Animal animal) {//Animal animal = Dog Animal animal = Catif (animal instanceof Dog){animal.eat();//向下转型Dog dog = (Dog) animal;//强制从dog类转为animaldog.lookDoor();//就可以调子类成员方法了}/**** 向下转型容易出现的问题: classCastException----->类型转换异常** 出现问题的原因: 转型的时候,等号左右两边型号不一致** 解决方案:做判断* 关键字:instanceof关键字------>用来判断某个对象是否属于某种数据类型。 返回值为布尔类型* 格式:* 对象名 instanceof 类型--》关键字前面的类型是否属于关键字后面的类型** */if (animal instanceof Cat){animal.eat();Cat cat = (Cat) animal;cat.catchMouse();}}
}
多态练习
2)分析
3)代码实现
package com.atguigu.l_duotai;
/*** -USB接口类,包括开启功能、关闭功能* **/
public interface USB {void open();//不写abstract也可以void close();
}
package com.atguigu.l_duotai;
public class KeyBoard implements USB{//重写接口方法@Overridepublic void open() {System.out.println("键盘开启");}@Overridepublic void close() {System.out.println("键盘关闭");}
}
package com.atguigu.l_duotai;
/**Mouse类**/
public class Mouse implements USB{@Overridepublic void open() {//重写接口方法System.out.println("鼠标开启");}@Overridepublic void close() {System.out.println("鼠标关闭");}
}
package com.atguigu.l_duotai;public class NoteBook {public void start(){//成员方法System.out.println("开机了");}
/*** 接收TEST类传过来的Mouse对象*USB接收* USB是mouse的接口类型 USB usb = mouse* mouse是usb的接口实现类对象* 接口看成父类。接口实现类看成子类* 多态的体现* **/public void useUSB(USB usb){// USB usb = keyBoardusb.open();//多态调用usb.close();}public void stop(){System.out.println("关机了");}
}
package com.atguigu.l_duotai;
/*** 定义笔记本类,具备开机,关机和使用USB设备的功能,具体是什么USB设备,笔记本不关心,* 只要符合USB规格的设备都可以。鼠标和键盘要想在电脑上使用,* 那么鼠标和键盘也必须遵守USB规范,不然鼠标和键盘的生产出来无法使用* 描述笔记本类,实现笔记本使用USB鼠标、USB键盘** -USB接口,包括开启功能、关闭功能* -笔记本类,包含运行功能、关机功能、使用USB功能* -鼠标类,要符合USB* -键盘类,要符合USB接口** **/
public class Test01 {public static void main(String[] args) {NoteBook noteBook = new NoteBook();noteBook.start();//笔记本类调用笔记本类的成员方法开机Mouse mouse = new Mouse();noteBook.useUSB(mouse);//传了一个mouse对象给接口实现类MouseSystem.out.println("==================");KeyBoard keyBoard = new KeyBoard();noteBook.useUSB(keyBoard);noteBook.stop();}
}
object类
1)使用object接收所有类
class Person {}
class Student {}
public class Test {public static void main(String[] args) {Object per = new Person();Object stu = new Student();}
}
2)object类的结构图
下面我们一个个方法进行分析,看这些方法到底有什么作用:1. clone()保护方法,实现对象的浅复制,只有实现了Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常。2. getClass()final方法,返回 Class 类型的对象,反射来获取对象。3. toString()该方法用得比较多,一般子类都有覆盖,来获取对象的信息。4. finalize()该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。5. equals()比较对象的内容是否相等6. hashCode()该方法用于哈希查找,重写了equals 方法一般都要重写 hashCode 方法。这个方法在一些具有哈希功能 的 Collection 中用到。7. wait()wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。 wait() 方法一直等待,直到获得锁或者被中断。 wait(long timeout) 设定一个超时间隔,如果在规定时间 内没有获得锁就返回。调用该方法后当前线程进入睡眠状态,直到以下事件发生。其他线程调用了该对象的notify 方法。其他线程调用了该对象的notifyAll 方法。其他线程调用了interrupt 中断该线程。时间间隔到了。 此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。8. notify() 该方法唤醒在该对象上等待的某个线程。9. notifyAll()该方法唤醒在该对象上等待的所有线程。
3)object类的常用方法
(1)toString方法
class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class Test {public static void main(String[] args) {Person per = new Person("Mr.Q", 20);System.out.println(per);}
}
class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "名字为:" + this.name + ",年龄为:" + this.age;}
}public class Test {public static void main(String[] args) {Person per = new Person("Mr.Q", 20);System.out.println(per);}
}
package com.atguigu.b_object;import java.util.ArrayList;public class Test01 {public static void main(String[] args) {Person p1 = new Person("柳岩",36);Person p2 = new Person("涛哥",18);System.out.println(p1);System.out.println(p2);System.out.println(p1.toString());//com.atguigu.b_object.Person@135fbaa4System.out.println(p2.toString());//com.atguigu.b_object.Person@45ee12a7ArrayList<String> list = new ArrayList<>();list.add("abc");list.add("def");System.out.println(list);// [abc, def]}
}
(2)equals方法
package com.atguigu.b_object;public class Test02 {public static void main(String[] args) {// 创建两个Person对象,内容相同Person p1 = new Person("柳岩",36);Person p2 = new Person("柳岩",36);// 使用equals方法比较p1和p2,期望结果是false//System.out.println(p1.equals(p2));//false// 使用equals方法比较p1和ArrayList对象,期望结果是false//ArrayList<String> list = new ArrayList<>();//System.out.println(p1.equals(list));// 使用equals方法比较p1和null,期望结果是false//System.out.println(p1.equals(null));// 使用equals方法比较p1和自身,期望结果是trueSystem.out.println(p1.equals(p1));System.out.println("=========================");// 创建两个String对象,内容相同String s1 = new String("abc");String s2 = new String("abc");// 使用equals方法比较s1和s2,期望结果是trueSystem.out.println(s1.equals(s2));//true
//equals重写 String方法内容 所以结果是true 但在实际内存中,内存的地址不一样// 使用==比较s1和s2,期望结果是falseSystem.out.println(s1==s2);//false}
}
/***class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}// 重写equals方法,通过name和age来判断两个Person对象是否相等@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}if (obj == null || getClass() != obj.getClass()) {return false;}Person person = (Person) obj;return age == person.age && name.equals(person.name);}}*** **/
@Override
public boolean equals(Object obj) {// 判断是否为同一对象if (this == obj) {return true;}// 判断传入的对象是否为空或者是否属于要比较的类对象if (obj == null || getClass() != obj.getClass()) {return false;}// 向下转型,将 Object 类还原为 Person 类Person person = (Person) obj;// 比较 name 和 age 是否相等return age == person.age && Objects.equals(name, person.name);
}
(4)getclass方法和native方法
getclass方法
public class Person {private String name;private int age;// 默认构造函数public Person() {}// 带参数的构造函数public Person(String name, int age) {this.name = name;this.age = age;}// 获取名字public String getName() {return name;}// 设置名字public void setName(String name) {this.name = name;}// 获取年龄public int getAge() {return age;}// 设置年龄public void setAge(int age) {this.age = age;}// 重写toString方法@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
native方法