面向对象
设计对象并使用
类和对象
-
类:是一组相关属性和行为的集合,我们将其理解为是一张对象的设计图
-
对象:是真实存在的具体东西。
在Java中,必须先设计类,才能获得对象
类和对象的关系
-
依赖关系:Java中需要根据类,创建对象
-
数量关系:一个类,可以创建出多个对象
如何定义类
//如何定义类
public class 类名{
1.成员变量(代表属性,一般是名词。与定义变量的格式相同,不过需要放在方法外面)
2.成员方法(代表行为,一般是动词。与定义方法的格式相同,不过需去掉static关键字)
3.构造器
4.代码块
5.内部类
}
//示例
public class Store{
//属性(成员变量)
String product;
double price;
//行为(方法)
public void buy(){
System.out.println("商店买入商品");
}
public void sell(){
System.out.println("商店卖出商品");
}
}
如何得到类的对象
类名 对象名=new 类名();
//示例
Store p=new Store();
如何使用对象
-
访问属性:对象名.成员变量
-
访问行为:对象名.方法名(…)
-
public class Storetest { public static void main(String[] args){ //创建商店的对象 Store p=new Store(); //给商店赋值 p.product="酸奶"; p.price=5.5; //获取商店对象中的值 System.out.println(p.product); System.out.println(p.price); //调用商店中的方法 p.buy(); p.sell(); } }
类的几个补充注意事项
-
用来描述一些事物的类,专业叫做:Javabean类
在Javabean类中是不写main方法的
-
编写main方法的类,叫做测试类
我们可以在测试类中创建Javabean类的对象并进行赋值调用
-
打印对象名,可以看到对象的内存地址
System.out.println(p);
/*运行结果:Store@4554617c
全类名:包名+类名
*/
定义类的补充注意事项
-
类名首字母建议大写,需要见名知意,驼峰模式,不能用关键字,满足标志符规定
-
一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名
实际开发中建议还是一个文件定义一个class类
-
成员变量的完整定义格式是:修饰符 数据类型 变量名称 =初始化值;一般无需指定初始化值,存在默认值
对象成员变量的默认值规则
数据类型 | 明细 | 默认值 |
---|---|---|
基本类型 | byte、short、int、long | 0 |
float、double | 0.0 | |
boolean | false | |
引用类型 | 类、接口、数组、String | null |
封装
使用类设计对象时,将需要处理的数据以及处理这些数据的方法,设计到对象中
面向对象的三大特征:封装、继承、多态
对象代表什么,就得封装对应的数据,并提供数据对应的行为
封装的好处
-
更好的维护数据
-
使用者无需关心内部实现,只要知道如何使用即可
封装的设计规范:合理隐藏,合理暴露。
权限修饰符
用于修饰成员变量和成员方法
-
private:只能在同一个类中访问
-
私有成员变量(为了保证数据的安全性)
-
针对私有的成员变量,提供对应的setXxx和getXxx方法
set:设置
get:获取
-
public class Student{ private int age;//私有化 public void setAge(int age){ if(age>=1&&age<=120){ this.age=age; }else{ System.out.println("年龄有误,请检查是否为1~120之间"); } } public int getAge(){ return age;/*return this.age的this可省略,返回成员变量age*/ } }
public class StudentTest{ public static void main(String[] args){ Student stu1=new Student(); stu.setAge(20);/*只能通过setAge方法对age进行赋值,排除了错误数据录入的可能*/ int age=stu.getAge(); System.out.println(age); } }
-
-
(default):同一个类中,同一个包中(不写即代表默认)
-
protected:同一个类中,同一个包中,不同包的子类
-
public:任意位置访问
this关键字
this代表当前类对象的引用(地址)。即直接输出this是一个地址
哪一个对象调用方法,方法中的this,代表的就是哪一个对象。
this可以解决的问题
当局部变量和成员变量出现了重名的情况,Java使用的是就近原则
this可以区分局部变量和成员变量的重名问题
this关键字的作用
this可以调用本类成员(变量,方法)
this.本类成员变量
this.本类成员方法();
this.的省略规则:
本类成员方法:没有前提条件,this.可以直接省略
本类成员变量:方法中没有出现重名的变量,this.才可以省略
this内存图
构造方法(构造器)
-
构造器
初始化一个新建的对象
构建、创造对象的时候,所调用的方法
-
格式
-
方法名与类名相同,大小写也要一致
-
没有返回值类型,连void都没有
-
没有具体的返回值(不能由return带回结果数据)
-
-
构造方法的执行时机
在创建对象的时候,被调用执行
每创建一次对象,就会执行一次构造方法
-
构造方法的作用
-
本质的作用:创建对象
-
结合执行时机:可以创建对象的时候,给对象中的数据初始化
-
-
构造方法的注意事项
-
一个类中,没有编写构造方法,系统将会提供一个[默认的] [无参数]的构造方法
-
一个类中,如果手动编写了构造方法,系统将不会提供那个默认的无参构造了
建议:编写类的时候,无参构造,带参构造,全部手动给出
-
构造方法不允许手动调用(即使用stu.student()语句调用student构造方法会报错)
-
构造方法的重载:构造方法也是方法,允许重载关系的出现
-
构造方法的执行流程
标准JavaBean
JavaBean:实体类;封装数据的类(如:Student,Phone等)
标准JavaBean要求
-
这个类中的成员变量都要私有,并且要对外提供相应的getXxx,setXxx方法(快捷键:右键,Generate,Getter and Setter,全选)
-
类中提供无参,带参构造方法(快捷键:右键,Generate,Constructor,ctrl+A可全选,OK为带参,SelectNone为无参)
-
快捷:右键,Ptg To JavaBean
实体类的应用场景
实体类只负责数据存取,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。
//只负责数据存取
public class Student{
private String name;
private double score;
//getter setter方法
}
//数据的处理放于其他类
public class StudentOperator{
private Student s;
public Service(Student s){
this.student=s;
}
/*展示学生信息
计算学生平均成绩、总成绩等*/
}
对象内存图
两个引用指向相同地址会将前一个引用的变量重新进行复制
成员变量、局部变量区别
区别 | 成员变量 | 局部变量 | |
---|---|---|---|
类中位置不同 | 方法外 | 方法中 | |
初始化值不同 | 有默认初始化值 | 没有,使用前需要完成赋值 | |
内存位置不同 | 堆内存 | 栈内存 | |
生命周期不同 | 随着对象的创建而存在,随着对象的消失而消失 | 随着方法的调用而存在,随着方法运行的结束而消失 | |
作用域 | 在自己所属的大括号里(类) | 在自己所属的大括号里(方法) |
第一个程序
public class BookTest {
public static void main(String[] args){
Book book1=new Book("西游记","长篇小说","吴承恩","L-130","明代","人民文学出版社","已借出");
Book book2=new Book("红星照耀中国","纪实文学","埃德加·斯诺","J-251","1938","人民文学出版社","未借出");
Book book3=new Book("给我来个小和尚","漫画","郭斯特","M-089","2016","中国友谊出版社","已借出");
Book[] Books={book1,book2,book3};
BookService bookService=new BookService(Books);
bookService.start();
}
}
public class Book {
private String title;
private String type;
private String author;
private String location;
private String time;
private String publisher;
private String state;
public Book() {
}
public Book(String title, String type, String author, String location, String time, String publisher, String state) {
this.title = title;
this.type = type;
this.author = author;
this.location = location;
this.time = time;
this.publisher = publisher;
this.state = state;
}
/**
* 获取
* @return title
*/
public String getTitle() {
return title;
}
/**
* 设置
* @param title
*/
public void setTitle(String title) {
this.title = title;
}
/**
* 获取
* @return type
*/
public String getType() {
return type;
}
/**
* 设置
* @param type
*/
public void setType(String type) {
this.type = type;
}
/**
* 获取
* @return author
*/
public String getAuthor() {
return author;
}
/**
* 设置
* @param author
*/
public void setAuthor(String author) {
this.author = author;
}
/**
* 获取
* @return location
*/
public String getLocation() {
return location;
}
/**
* 设置
* @param location
*/
public void setLocation(String location) {
this.location = location;
}
/**
* 获取
* @return time
*/
public String getTime() {
return time;
}
/**
* 设置
* @param time
*/
public void setTime(String time) {
this.time = time;
}
/**
* 获取
* @return publisher
*/
public String getPublisher() {
return publisher;
}
/**
* 设置
* @param publisher
*/
public void setPublisher(String publisher) {
this.publisher = publisher;
}
/**
* 获取
* @return state
*/
public String getState() {
return state;
}
/**
* 设置
* @param state
*/
public void setState(String state) {
this.state = state;
}
}
import demo.Movie;
import java.util.Objects;
import java.util.Scanner;
public class BookService {
private Book[] books;
Scanner sc = new Scanner(System.in);
public BookService(Book[] books) {this.books = books;}
public void start() {
lo:
while (true) {
System.out.println("-----------图书查询系统-----------");
System.out.println("请输入您的选择:");
System.out.println("1.按书名查找");
System.out.println("2.按作者查找");
System.out.println("3.按类型查找");
System.out.println("4.退出");
int choice = sc.nextInt();
switch (choice) {
case 1:
compare1();
break;
case 2:
compare2();
break;
case 3:
compare3();
break;
case 4:
System.out.println("感谢您的使用,小图期待与您的下次相遇!");
break lo;
default:
System.out.println("您的输入有误,请检查!");
break;
}
}
}
private void compare1() {
//1.键盘录入用户输入的书名
System.out.println("请输入您要查询的图书名称:");
String title = sc.next();
//2.遍历数组,从数组中查询书籍信息
for (int i = 0; i < books.length; i++) {
Book book = books[i];
if(Objects.equals(book.getTitle(), title)) {
//将找到的图书信息,打印在控制台
System.out.println(book.getTitle() + "---" + book.getAuthor() + "---" + book.getTime() + "---" + book.getType() + "---" + book.getPublisher()+"---" + book.getLocation() + "---" + book.getState());
return;
}
}
//代码走到这里,说明没找到
System.out.println("您想要查找的书籍名称有误或小图暂未上架相关作品ಥ_ಥ请重新输入");
}
private void compare2() {
//1.键盘录入用户输入的作者名
System.out.println("请输入您要查询的作者:");
String author = sc.next();
for (int i = 0; i < books.length; i++) {
Book book = books[i];
if(Objects.equals(book.getAuthor(), author)) {
System.out.println(book.getTitle() + "---" + book.getAuthor() + "---" + book.getTime() + "---" + book.getType() + "---" + book.getPublisher()+"---" + book.getLocation() + "---" + book.getState());
return;
}
}
System.out.println("您想要查找的作者名字有误或小图暂未上架相关作品ಥ_ಥ请重新输入");
}
private void compare3() {
//1.键盘录入用户输入的类型
System.out.println("请输入您要查询的图书类型:");
String type = sc.next();
for (int i = 0; i < books.length; i++) {
Book book = books[i];
if(Objects.equals(book.getType(), type)) {
System.out.println(book.getTitle() + "---" + book.getAuthor() + "---" + book.getTime() + "---" + book.getType() + "---" + book.getPublisher()+"---" + book.getLocation() + "---" + book.getState());
return;
}
}
System.out.println("您想要查找的书籍类型有误或小图暂未上架ಥ_ಥ请重新输入");
}
private void publish() {
//遍历数组,取出每一个书籍对象
for (int i = 0; i < books.length; i++) {
Book book = books[i];
//通过书籍对象,调用内部get方法,获取信息并打印
System.out.println(book.getTitle() + "---" + book.getAuthor() + "---" + book.getTime() + "---" + book.getType() + "---" + book.getPublisher() + "---" + book.getLocation() + "---" + book.getState());
}
}
}