主,你是伟大的,你应受一切赞美;你有无上的能力、无限的智慧
--奥古斯都《忏悔录》
一、封装的含义
1、封装的概念
封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在java中通过关键字private,protected和public实现封装。什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。
2、好处
- 将变化隔离。
- 便于使用。
- 提高重用性。
- 提高安全性。
3、封装原则
- 将不需要对外提供的内容都隐藏起来。
- 把属性都隐藏,提供公共方法对其访问
二、private(私有)关键字
1、private关键字:
- 是一个权限修饰符。
- 可以修饰成员(成员变量和成员方法)
- 被private修饰的成员只有本类中才能访问
2、private最常见的应用:
- 把成员变量用private修饰
- 提供对应的getXxx()/setXxx()方法
- 一个标准的案例的使用
注意:私有仅仅是封装的一种表现形式。之所以提供对外访问方式,就因为可以在访问方式中加入逻辑判断等语句。而不是直接对变量操作,而是对访问的数据进行操作。提高代码健壮性,使代码更符合人类的逻辑。
三、this关键字
1、引入
如果有同一个类型的两个对象,分别是a和b。如何才能让两个对象都能调用到peel()办法呢?
class Banana {
void peel(int i){
//....
}
}
public class BananaPeel {
public static void main(String[] args) {
Banana a = new Banana(),
b = new Banana();
a.peel(1);
a.peel(2);
}
}
只有一个peel()方法,它如何知道是被a还是被b所调用呢?
为了简便,编译器自己“偷偷”地做了写幕后工作,它暗自把“所操作的对象的引用”作为第一个参数传递给peel()。将方法的调用变成了
Banana.peel(a, 1)
Banana.peel(b, 2)
但这是代码的内部表示形式,我们不能这样写,由此引出this关键字。
2、概念
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。
注意:如果在方法内部调用同一类中的其他方法,就不必使用this,直接调用即可
3、案例
public class This_function {
public static void main(String[] args) {
new Person().eat(new Apple());
}
}
class Person{
public void eat(Apple apple){
Apple peeled = apple.getPeeled();
System.out.println("Yummy");
}
}
class Peeler{
static Apple peel(Apple apple){
return apple;
}
}
class Apple{
Apple getPeeled(){
return Peeler.peel(this);
}
}
四、构造方法
1、构造方法作用概述
在Java中,通过提供构造器,类的设计者可以保障每个对象都会得到初始化。创建对象时,如果其类具有构造器,Java就会在用户有能力操作对象之前自动调动相应的构造器。从而保证初始化的执行。
2、构造方法格式
- 方法名与类名相同。
- 没有返回值类型,连void都没有。
- 没有具体的返回值。
注意:由于构造器的名称必须与类名完全相同,所以”每个方法首字母小写“的编码风格并不适用于构造器。
class Rock{
Rock(int i){
System.out.println("Rock" + i + " ");
}
}
public class SimpleConstructor {
public static void main(String[] args) {
for (int i = 0; i < 8; i++) {
new Rock(i);
}
}
}
/*
output:
Rock0
Rock1
Rock2
Rock3
Rock4
Rock5
Rock6
Rock7
*/
不接受任何参数的构造器叫做默认构造器,Java文档中通常采用术语无参构造器
如果有构造器形式参数,就可以在初始化对象的时候提供实际的参数。例如:假设一个Tree类构造器,接受一个整型变量来表示树的高度,就可以这样创建一个Tree对象:
Tree t = new Tree(12) // 12-foot tree
五、一个标准类的3.0版本的写法
package standard_class
/*
一个标准类的3.0版本写法
类:
成员变量:使用private关键字进行修饰。
构造方法:提供一个无参数的构造方法,以及一个有参数的构造方法。
成员方法:getXxx()和setXxx()。
show():展示成员变量值的情况。
*/
class Animal {
private String name;
private String kind;
private int count;
public Animal(){
}
public Animal(int count, String kind, String name) {
this.count = count;
this.kind = kind;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void show(){
System.out.println("物种名:" + this.name + " ,物种类:" + this.kind + "物种数量:" + this.count);
}
}
public class Test {
public static void main(String[] args) {
//先使用无参数构造方法把对象创建出来,然后使用setXxx()对成员变量进行赋值。
Animal a1 = new Animal();
a1.setName("老虎");
a1.setKind("猫科");
a1.setCount(15);
a1.show();
//直接调用有参数的构造方法创建对象,在创建对象的同时给成员变量赋值。
Animal a2 = new Animal(1000,"犬科","金毛");
}
}
六、对象的初始化过程
1、一个对象的初始化过程
Student s1 = new Student()
顺序:
先将student类加载到方法区中-->
在栈中为s1变量开辟空间-->
在堆内存中为s1对象开辟空间-->
给成员变量赋予系统默认值-->
显示初始化-->
构造方法初始化-->
将堆内存中的对象地址值赋给栈中的变量s1-->
后续可以通过方法对成员变量再进行修改值
//创建第一个学生对象
Student s1 = new Student();
s1.id = "1234567" ; //输入学号
s1.name = "张三"; //输入姓名
s1.age = 17; //输入年龄
System.out.println("学号:" + s1.id + ", 姓名:" + s1.name + "年龄:" + s1.age);
s1.playGame("原神");
//定义第二个变量,将第一个对象的地址值赋值给这个变量
Student s2 = s1;
s2.age = 100;
System.out.println("学号:" + s1.id + ", 姓名:" + s1.name + "年龄:" + s1.age)
System.out.println("学号:" + s2.id + ", 姓名:" + s2.name + "年龄:" + s2.age)
2、图解
七、static关键字
1、static的含义
在了解this关键字之后,就可以更全面的理解static(静态)方法的含义。static方法就是没有this的方法。static关键字在Java中可以修饰成员变量和成员方法。
2、static关键字特点
- 随着类的加载而加载
- 优先于对象存在
- 被类的所有对象共享(这也是我们判断是否使用静态关键字的条件)
- 可以通过类名调用
3、static关键字注意事项
- 在静态方法中是没有this关键字的
- 静态方法只能访问静态的成员变量和静态的成员方法
八、帮助文档用法
https://docs.oracle.com/en/java/javase/22/docs/api/index.html
帮助手册可以在置顶处下载
1、如何使用帮助文件
(1)双击打开
(2)点击搜索,输入要查询的类
(3)先观察所属包,若属于java.lang包下的话,不用导包直接使用,否则需要导包才能使用。
(4)看类的关系(继承关系和实现关系)
(5)看类的描述
(6)看构造方法。若没有构造方法,大概率是工具类
(7)看成员变量
(8)看成员方法
九、代码块
在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
局部代码块 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
构造代码块 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块 在类中方法外出现,加了static修饰 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。
// 前三个代码块和构造方法之间的执行顺序:
// 静态代码块 - 构造代码块 - 构造方法
public class CodeDemo1 {
//无参构造方法
CodeDemo1(){
System.out.println("慕然回首,那人已在灯火阑珊处"); // 3
}
//构造代码块
{
System.out.println("昨夜西风凋碧树。独上高楼,望尽天涯路"); // 2
}
//最先执行的
static {
System.out.println("衣带渐宽终不悔,为伊消得人憔悴"); // 1
}
public static void main(String[] args) {
//局部代码块
// {
// int a = 10;
// System.out.println(a); // 2
// }
// System.out.println("好好学习,天天向上!");
// //局部代码块
// {
// int b = 20;
// System.out.println(b);
// }
// System.out.println(a); // 用不到局部代码块中的定义的变量
CodeDemo1 codeDemo1 = new CodeDemo1();
CodeDemo1 codeDemo2 = new CodeDemo1();
}
}
十、引用数据类型和基本数据类型当作参数
- 当基本数据类型作为方法的参数类型的时候,将来调用时需要传入具体的数值。
- 当引用数据类型作为方法的参数类型的时候,将来调用时需要传入该引用数据类型的对象。
十一、封装的练习
-- 1、定义一个员工类,自己分析出几个成员,然后给出成员变量,
构造方法,getXxx()/setXxx()方法,以及一个显示所有成员信息的方法。并测试。
-- 2、定义一个长方形类,定义 求周长和面积的方法,然后定义一个测试了Test2,进行测试。
-- 3、定义一个类Demo,其中定义一个求两个数据和的方法,定义一个测试了Test,进行测试。
-- 4、定义一个类MyMath,提供基本的加减乘除功能,然后进行测试
-- 5、使用面向对象的思想,编写自定义描述狗的信息。设定属性包括:品种,年龄,心 情,名字;方法包括:叫,跑。
要求:
1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问
2)限定心情只能有“心情好”和“心情不好”两种情况,如果无效输入进行提示, 默认设置“心情好”。
3)设置构造函数实现对属性赋值
4)叫和跑的方法,需要根据心情好坏,描述不同的行为方式。
5)编写测试类,测试狗类的对象及相关方法(测试数据信息自定义)
-- 6、以面向对象的思想,编写自定义类描述 IT 从业者。设定属性包括:姓名,年龄, 技术方向,工作年限, 工作单位和职务;方法包括:工作
要求:
1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问
2)限定 IT 从业人员必须年满 15 岁,无效信息需提示,并设置默认年龄为 15。
3)限定“技术方向”是只读属性(只提供 get 方法)
4)工作方法通过输入参数,接收工作单位和职务,输出个人工作信息
5)编写测试类,测试 IT 从业者类的对象及相关方法(测试数据信息自定义)
--7、以面向对象的思想,编写自定义类描述图书信息。设定属性包括:书名,作者,出 版社名,价格;方法包括:信息介绍 show()
要求:
1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问
2)限定价格必须大于 10,如果无效进行提示
3)限定作者,书名为只读属性
4)设计构造方法实现对属性赋值
5)信息介绍方法描述图书所有信息
6)编写测试类,测试图书类的对象及相关方法(测试数据信息自定)
-- 8、4.某公司要开发名为”我爱购物狂”的购物网站,请使用面向对象的思想设计描述商 品信息
要求:
1)分析商品类别和商品详细信息属性和方法,设计商品类别类和商品详细信息类
2)在商品详细信息类中通过属性描述该商品所属类别
3)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问
4)编写测试类,测试商品类别类和商品详细信息类的对象及相关方法(测试数据 信息自定)
5)创建包 info—存放商品类别类和商品详细信息类,创建包 test—存放测试类参考分析思路:
商品类别类:
属性:类别编号,类别名称商品详细信息类:
属性:商品编号,商品名称,所属类别,商品数量(大于 0),商品价格(大于 0),
方法:盘点的方法,描述商品信息。内容包括商品名称,商品数量,商品价格, 现在商品总价以及所属类别信息
十二、答案
-- 1、
class staff{
private String name;
private int age;
private String sex;
private int salary;
public staff() {
}
public staff(String name, int age, String sex, int salary) {
this.name = name;
this.age = age;
this.sex = sex;
this.salary = salary;
}
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public void show(){
System.out.println("姓名:"+this.name+" 年龄:"+this.age+" 性别:"+this.sex+" 工资:"+this.salary);
}
}
public class HomeWork01 {
public static void main(String[] args) {
staff st1 = new staff("小白文",26,"男",20000);
staff st2 = new staff();
st2.setName("小虎");
st2.setAge(26);
st2.setSex("男");
st2.setSalary(20000);
st1.show();
st2.show();
}
}
-- 2、
import java.util.Scanner;
class Rectangular{
public Rectangular() {
}
int perimeter(int length,int width){
return (length+width)*2;
}
int area(int length,int width){
return length*width;
}
}
public class HomeWork02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int length = sc.nextInt();
int width = sc.nextInt();
Rectangular r = new Rectangular();
System.out.println("长方型的面积: "+r.area(length,width));
System.out.println("长方型的周长:"+r.perimeter(length,width));
}
}
-- 3、
import java.util.Scanner;
class Demo{
private int num1;
private int num2;
public Demo() {
}
public Demo(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
int sum(){
return (num2+num1);
}
}
public class HomeWork03 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Demo d = new Demo();
d.setNum1(sc.nextInt());
d.setNum2(sc.nextInt());
System.out.println(d.sum());
}
}
-- 4、
import java.util.Scanner;
//定义一个类MyMath,提供基本的加减乘除功能,然后进行测试
class MyMath{
public int sum(int a, int b){
return (a+b);
}
public int subtraction(int a, int b){
return (a-b);
}
public int multiplication(int a, int b){
return (a*b);
}
public int division(int a, int b){
return (a/b);
}
public int remainder(int a, int b){
return (a%b);
}
}
public class HomeWork04 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
MyMath mm = new MyMath();
System.out.println(mm.sum(a,b));
System.out.println(mm.subtraction(a,b));
System.out.println(mm.multiplication(a,b));
System.out.println(mm.division(a,b));
System.out.println(mm.remainder(a,b));
}
}
-- 5、
class Dog { //老师的修改版本,后几题未经修改,请参照此题略做修改
private String breed;
private int age;
private String feel;
private String name;
public Dog() {//无参的构造函数
}
public Dog(String breed, int age, String feel, String name) {
this.breed = breed;
this.age = age;
setFeel(feel);
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFeel() {
return feel;
}
public void setFeel(String feel) {
if (feel .equals("心情好") || feel .equals("心情不好")) {
this.feel = feel;
} else {
this.feel = "心情好";
System.out.println("无效输入");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void cry(){
if(feel .equals("心情好") ){
System.out.println("高兴的叫");
}else {
System.out.println("不高兴的叫");
}
}
public void run(){
if(feel .equals("心情好") ){
System.out.println("高兴的跑");
}else {
System.out.println("不高兴的跑");
}
}
}
public class HomeWork01 {
public static void main(String[] args) {
// Scanner sc = new Scanner(System.in);
// System.out.println("请输入有几条狗:");
// int num = sc.nextInt();
// for (int i = 0; i < num; i++) {
// Dog d = new Dog();
// System.out.println("请输入狗的品种:");
// d.setBreed(sc.next());
// System.out.println("请输入狗的年龄:");
// d.setAge(sc.nextInt());
// System.out.println("请输入狗的心情:");
// int a = d.setFeel(sc.next());
// if(a==-1){
// break;
// }
// System.out.println("请输入狗的姓名:");
// d.setName(sc.next());
// d.cry();
// d.run();
// }
Dog d1 = new Dog("泰迪",1,"心情好","旺财1");
Dog d2 = new Dog("金毛",2,"心情不好","旺财2");
Dog d3 = new Dog("藏獒",5,"好","旺财3");
Dog d4 = new Dog("吉娃娃",3,"心情不好","旺财4");
Dog d1 = new Dog("a1", 1, "qwerr", "aa1");
Dog d2 = new Dog("a2", 2, "心情不好", "aa2");
System.out.println(d1.getFeel());
System.out.println(d2.getFeel());
}
}
-- 6、
import java.util.Scanner;
class ITman{
private String name;
private static int age=15;
private String Technical_Direction;
private int work_year;
private String Work_unit;
private String position;
public ITman() {
}
public ITman(String name, String technical_Direction, int work_year, String work_unit, String position) {
this.name = name;
Technical_Direction = technical_Direction;
this.work_year = work_year;
Work_unit = work_unit;
this.position = position;
}
public ITman(String technical_Direction) {
Technical_Direction = technical_Direction;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getAge() {
return age;
}
public static int setAge(int age) {
if (age < 15){
ITman.age = 15;
return -1;
}else{
ITman.age = age;
}
return 0;
}
public String getTechnical_Direction() {
return Technical_Direction;
}
// public void setTechnical_Direction(String technical_Direction) {
// Technical_Direction = technical_Direction;
// }
public int getWork_year() {
return work_year;
}
public void setWork_year(int work_year) {
this.work_year = work_year;
}
public String getWork_unit() {
return Work_unit;
}
public void setWork_unit(String work_unit) {
Work_unit = work_unit;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public void Work( ){
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
System.out.println("技术方向:"+getTechnical_Direction());
System.out.println("工作年限:"+work_year);
System.out.println("目前就职于:"+getWork_unit());
System.out.println("职务是:"+position);
System.out.println("======================================");
}
}
public class HomeWork02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入有几个人:");
int num = sc.nextInt();
for (int i = 0; i < num; i++) {
System.out.println("请输入技术方向:");
ITman m = new ITman(sc.next());
System.out.println("输入姓名:");
m.setName(sc.next());
System.out.println("请输入年龄:");
int a = m.setAge(sc.nextInt());
if (a==0){
} else if (a==-1) {
System.out.println("无效输入");
}
System.out.println("请输入工作年限:");
m.setWork_year(sc.nextInt());
System.out.println("请输入工作单位:");
m.setWork_unit(sc.next());
System.out.println("请输入职务:");
m.setPosition(sc.next());
m.Work();
}
}
}
-- 7、
import java.util.Scanner;
class book{
private String book_name;
private String author;
private String publisher;
private static double price=10.0;
public book() {
}
public book(String book_name, String author, String publisher, double price) {
this.book_name = book_name;
this.author = author;
this.publisher = publisher;
this.price = price;
}
public book(String book_name, String author) {
this.book_name = book_name;
this.author = author;
}
public String getBook_name() {
return book_name;
}
// public void setBook_name(String book_name) {
// this.book_name = book_name;
// }
public String getAuthor() {
return author;
}
// public void setAuthor(String author) {
// this.author = author;
// }
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public double getPrice() {
return price;
}
public double setPrice(double price) {
if(price < 10.0){
System.out.println("输入无效");
return -1;
}else{
this.price = price;
}
return 0;
}
public void show() {
System.out.println("书名:"+book_name);
System.out.println("作者:"+author);
System.out.println("出版社:"+publisher);
System.out.println("价格:"+price);
System.out.println("=====================");
}
}
public class HomeWork03 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入人数:");
int num = sc.nextInt();
for (int i = 0; i < num; i++) {
System.out.println("请输入作者名和书名:");
book b = new book(sc.next(), sc.next());
System.out.println("请输入出版社:");
b.setPublisher(sc.next());
System.out.println("请输入价格:");
double a=b.setPrice(sc.nextDouble());
if(a == -1){
System.out.println("无效输入:(设为默认值:10)");
}
b.show();
}
}
}
第八题较为特殊,所放答案为标准答案,需要创建两个包和三个类,我将按自上而下的顺序分别书写,如图所示
package HomeWork04_info;
public class Product {
private String pid;
private String name;
private int amount;
private double price;
private ProductCategory category;
public Product() {
}
public Product(String pid, String name, int amount, double price) {
super();
this.pid = pid;
this.name = name;
this.amount = amount;
this.price = price;
}
public Product(String pid, String name, int amount, double price, ProductCategory category) {
super();
this.pid = pid;
this.name = name;
this.setAmount(amount);
this.price = price;
this.category = category;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
if(amount<0){
System.out.println("库存数量异常,请联系管理员");
this.amount = 0;
}else{
this.amount = amount;
}
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public ProductCategory getCategory() {
return category;
}
public void setCategory(ProductCategory category) {
this.category = category;
}
public void check(){
System.out.println("商品名称:"+this.name);
System.out.println("所属类别:"+this.category.getName());
System.out.println("库存数量:"+this.price);
System.out.println("商品售价:"+this.amount);
System.out.println("商品总价:"+this.price*this.amount);
}
}
package HomeWork04_info;
public class ProductCategory {
private String cid;
private String name;
public ProductCategory() {
}
public ProductCategory(String cid, String name) {
super();
this.cid = cid;
this.name = name;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package HomeWork04_Test;
import HomeWork04_info.Product;
import HomeWork04_info.ProductCategory;
public class ProductTest {
public static void main(String[] args) {//指定商品信息并盘点
ProductCategory category1 = new ProductCategory("11", "洗发水");
Product p1 = new Product("111", "潘婷洗发水400ml",
16, 40.5, category1);
p1.check();
System.out.println("==============");
//指定商品信息并盘点
Product p2 = new Product();
p2.setPid("222");
p2.setName("蜂花洗发水250ml");
p2.setPrice(11.5);
p2.setAmount(-5);
p2.setCategory(category1);
p2.check();
}
}