文章目录
面向对象有三大特性 : 封装 继承 多态
封装
程序设计中遇到的问题
public class Student {
String name;
int age;
String sex;
String birthday;
}
测试类中引用
Student stu = new Student();
stu.name = "于志强";
stu.sex = "男";
stu.age = 2000;
程序设计的缺陷
外界可以随意的对对象的属性进行修改,赋值操作,没有任何约束
封装
实质是, 将类的状态隐藏在类内部, 不允许外部程序直接访问, 而是通过该类提供的方法来实现对隐藏信息的操作和访问
优势
- 反映了事物的相对独立性, 有效地避免了外部错误对对象的影响
- 隐藏类的实现细节,让使用者只能通过规定方式访问数据, 限制不合理操作
使用方式
private int age;
/**
* 给age 创建相对应的方法
* 通过方法内部的逻辑 来限制外界的访问
*/
public void setAge(int age){
// 如果年龄在 0-127岁之间可以赋值
if(age > 0 && age < 127){
this.age = age;
}else{
System.out.println("年龄设置有误!");
}
}
public int getAge(){
return age;
}
举个栗子
想见明星
先和经纪人 预约, 经纪人条件列出来给你,出场费一百万
包结构
包的作用
- 包可以将类组成较小的单元 (类似于文件夹)
- 防止命名冲突 (学生 中学生middle 大学生college)
- 允许制定规则在更广的范围内保护类,数据和方法
语法标准
// 声明 必须位于 java源文件的第一条非注释语句
package 包结构;
包结构通用规范
- 一个唯一的包,前缀通常是小写的ASCII 字母, 并且是一个顶级域名,(com,cn,edu,gov,net,org)通常使用组织的网络域名的逆序 (cn.bdqn)
- 域名.公司名.项目名.项目模块名
使用包结构
import college.Student;
回忆使用Scanner 类
import java.util.Scanner;
访问权限修饰符
包结构是一种访问控制机制,可以通过包限制和制约类之间的访问关系
类的访问修饰符
| 修饰符 | 同一个包 | 不同包 |
|---|---|---|
| public | 可以使用 | 可以使用 |
| 默认的 | 可以使用 | 不可以使用 |
类成员的修饰符
| 修饰符 | 同一个类中 | 同一包中 | 子类 | 不同包 |
|---|---|---|---|---|
| public (公共的) | √ | √ | √ | √ |
| protected (受保护的) | √ | √ | √ | × |
| 默认 | √ | √ | × | × |
| private(私有的) | √ | × | × | × |
static 修饰符
概念
static 含义 静态的 表示一个类中的属性或者方法是被该类的所有对象所共享
举个栗子
学生是一个类
个性: 学生的姓名, 年龄都是属于一个学生的特性
共性: 大家同处于一个教室 , 教室是属于大家的, 不是属于某一个学生的
该属性 是公共的 不单独属于某一个对象,而是属于所有对象
因为对象 都是从类中实例化出来的(类是一个模板,对象是基于该模板的一个实例)
静态属于所有对象, 静态是属于类的 属于模板的
教室中有饮水机 , 所有学生都可以使用, 但是没有所有权,只有使用权
静态属性的调用
public class Student {
static String classRoom = "公用机房";
String name;
}
Student stu1 = new Student();
stu1.name = "张三";
System.out.println(stu1.classRoom);
Student stu2 = new Student();
stu2.name = "李四";
System.out.println(stu2.classRoom);
使用对象调用静态 是不推荐的, 最好方式是使用类名调用
Student.classRoom
学习静态static之前
成员属性
成员方法构造方法
成员代码块

学习静态static之后
成员属性
成员方法
成员代码块
静态属性
静态方法
静态代码块
构造方法

静态和非静态的执行顺序
静态 > 非静态
非静态 依赖于对象而存在的, 没有对象就没有非静态的属性
学生的姓名 是非静态, 如果没有学生对象就没有姓名
静态 依赖于类存在,不依赖对象, 跟随类的加载而加载
教室 即使没有开学, 没有一个学生, 教室依然存在
// 在没有创建任何对象的时候, 就可以使用 classRoom 属性
System.out.println(Student.classRoom);
// 如果想要使用非静态name属性 必须创建对象
Student stu = new Student();
stu.name = "张三";
System.out.println(stu.name);
类变量和实例变量的对比
类变量(静态变量)
被static修饰的变量
在内存中只有一个拷贝
类内部,可在任何方法内直接访问静态变量
其他类中,可以直接通过类名访问
实例变量
没有被static修饰的变量
每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响

程序运行流程
- 静态属性
- 静态代码块
- 成员属性
- 构造代码块
- 构造方法
静态代码只会加载一次 , 静态内容在内存中只有一份
非静态, 每一次创建对象都会被运行一次
静态和非静态之间的相互调用
非静态可以使用 静态方法和静态属性
静态方法不可以使用非静态属性和非静态方法 包括this关键字
public class Student {
static String classRoom = "公用机房";
// 依赖于某个具体对象的 没有一个存在的学生, 就没有学生姓名
String name;
public void study(){
// 不会产生冲突问题
System.out.println(name +"在"+classRoom+"学习");
}
// 静态方法 可以直接使用类名来调用 , 不依赖于某一个具体对象
public static void abc(){
// name 依赖于某个具体对象的 没有一个存在的学生, 就没有学生姓名
// 冲突问题
System.out.println(name +"在"+classRoom+"学习");
}
}
案例
模拟实现选民投票过程:一群选民进行投票,每个选民只允许投一次票,并且当投票总数达到100时,就停止投票
投票次数 属于选民的, 属于所有选民,而不是某一个选民
继承
书写两个类
猫狗案例 , 有很多相同的属性 方法
抽取类之间的共性, 成为父类(动物)
继承的语法
子类 extends 父类 (is a 是一个 的关系)
public class Animal {
String type;
String name;
String sex;
int age;
public void sleep(){}
public void eat(){}
}
public class Dog extends Animal{
public void lookDoor(){}
}
public class Cat extends Animal{
public void catchMouse(){}
}
特性
继承是Java中实现代码重用的重要手段之一。
Java中只支持单根继承,即一个类只能有一个直接父类
子类继承父类, 继承了父类所有非私有的属性和方法
子类调用父类的内容
语法
// 调用父类属性
super.name
// 调用父类的方法
super.eat();
// 调用父类的构造
super();
super(name);
注意点
super 只能出现在子类的方法和构造方法中
super 调用构造方法时,只能是第一句
super 不能访问父类的private成员
继承条件下的构造方法
1- 创建子类对象 默认去调用 父类的无参构造
2- 子类继承父类, 拥有了父类的所有的非私有属性, 子类就可以对这些属性进行操作
3- 构造方法就是给属性进行初始化的 , 子类构造方法没有通过super显式调用父类的有参构造方法,也没通过this显式调用自身其他构造方法 , 系统默认调用父类的无参构造方法4- 子类构造方法通过super显式调用父类的有参构造方法, 执行父类相应构造方法,而不执行父类无参构造方法
子父类之间代码执行流程
在有继承关系的两个类, 代码中的内容是如何执行的
class Father{
属性
构造代码块
构造方法
}
class Son extends Father{
属性
构造代码块
构造方法
}
流程
父类的 属性 > 构造代码块 > 构造方法
子类的 属性 > 构造代码块 > 构造方法
在有静态内容加入的情况下
class Father{
静态属性
静态构造代码块
属性
构造代码块
构造方法
}
class Son extends Father{
静态属性
静态构造代码块
构造方法
}
1- 父类的静态属性, 静态代码块
2- 子类的静态属性, 静态代码块
3- 父类的成员属性,成员代码块, 构造方法
4- 子类的成员属性,成员代码块, 构造方法
子类不能获取父类的哪些资源
- private成员
- 子类与父类不在同包 , 使用默认访问权限的成员
- 构造方法
方法重写
概念 :
子类根据需求对从父类继承的方法进行重新编写
重写时,可以用super.方法的方式来保留父类的方法
构造方法不能被重写 (子类不能继承父类的构造方法)
方法重写的规则
方法重写(override): 发生在两个有继承关系的类中, 子类重写继承自父类的方法, 要求方法名,参数列表,返回值一致, 访问修饰符权限不能低于父类,抛出异常不能高于父类
方法重载(overload): 发生在同一个类中, 方法名相同,参数列表不同,与访问修饰符,返回值类型无关
- 方法名相同
- 参数列表相同
- 返回值相同或是其子类
- 访问修饰符权限不能低于父类
- 抛出异常不能高于父类

Object 类
默认是所有类的父类
一个类如果不写 extends 默认继承Object类
Object(超类) 中国人 是炎黄子孙, 龙的传人

toString()
A a = new A("李四",20);
// System.out.println(a.toString()); // date0710.A@1b6d3586
// 对象是在堆内存中保存的, 都拥有一个地址信息 1b6d3586 十六进制的地址表示方式
// 如果用户不希望看到类似于 date0710.A@1b6d3586 打印效果, 可以重写该方法
System.out.println(a); // 默认去调用 该对象的 toString()方法
equals()
== 比较运算符
如果比较的是两个基本数据类型 含义是直接比较值的大小
如果比较的是两个引用数据类型 含义是比较两个对象是否是同一对象
Object中 equals()方法 源码
public boolean equals(Object obj) {
return (this == obj);
}
案例
public class Student {
int sId;
String name;
public Student(){}
public Student(int sId,String name){
this.sId = sId;
this.name = name;
}
@Override
public boolean equals(Object obj) {
// 强转类型
Student stu = (Student)obj;
return this.sId == stu.sId;
}
}
public static void main(String[] args) {
Student s1 = new Student(10086,"张三");
Student s2 = new Student(10086,"张三");
// 两名学生 学号一致 就是同一个人
System.out.println(s1.equals(s2)); // 使用父类的 equals s1 == s2
}
含义
Object 中的方法, 用于比较两个对象的地址是否相同, 一般要求子类重写, 用于比较两个对象的内容是否一致
本文详细探讨了Java面向对象的两大特性——封装和继承。封装旨在隐藏类的内部状态,防止外部直接访问,提高代码安全性。介绍了包的作用、访问权限修饰符以及static修饰符的使用。在继承部分,解释了如何通过继承实现代码重用,讨论了子类调用父类内容的规则,以及方法重写的基本概念和规则。同时,还涉及到Object类及其默认的equals()和toString()方法。
530

被折叠的 条评论
为什么被折叠?



