学习目标:
- Java 在大三上已经学过一学期的面向对象,所以打算在一星期把面向对象复习完成。
学习内容:
- 类和对象
- 封装
- 就近原则和this关键字
- 构造方法
- 标准的javabean类
- 基本数据类型和引用数据类型
- 成员和局部
学习时间:
- 下午4点—晚上9点
学习产出:
1.类和对象
类:是对共同特征的描述。
对象:是真实存在的具体东西。
在Java中,必须先设计类,才能获得对象。
类名首字母大写,需要见名知意,驼峰模式。
一个Java中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。
设计开发中建议还是一个文件定义一个class类。
成员变量的完整定义格式为:修饰符 数据类型 变量名=初始化值;一般无需指定初始化值,存在默认值。
定义类
public class 类名{
1.成员变量(代表属性,一般名词)
2.成员方法(代表行为,一般动词)
3.构造器(后面学习)
4.代码块(后面学习)
5.内部类(后面学习)
}
如何获得类的对象
类名 对象名=new 类名();
Phone p=new Phone();
下面来写一个具体的例子
首先在idea中新建一个Java Class命名为phone,在phone这个类中创建phone的属性(成员变量):brand、price,在类中构造方法(public void 方法名())。
public class phone {
//属性(成员变量)
String brand;
double price;
//行为(方法)
public void call(){
System.out.println("手机在打电话");
}
public void playGame(){
System.out.println("手机在玩游戏");
}
}
创建一个测试类与上文创建方法一致,命名为phoneTest。测试类中包含两个对象,给对象赋值格式为:创建的对象名.成员变量=所赋的值。调用类中方法格式为:创建的对象名.方法名()。
public class phoneTest {
public static void main(String[] args) {
//创建手机对象
phone p=new phone();
//给手机赋值
p.brand="小米";
p.price=1299.9;
//获取手机对象的值
System.out.println(p.brand);
System.out.println(p.price);
p.call();
p.playGame();
phone p2=new phone();
p2.brand="苹果";
p2.price=8999;
System.out.println(p2.brand);
System.out.println(p2.price);
}
}
运行结果
小米
1299.9
手机在打电话
手机在玩游戏
苹果
8999.0
2.封装
封装为面向对象的三大特征之一(封装、继承、多态)。
封装告诉我们,如何正确设计对象的属性和方法。对象代表什么,就得封装对应的数据,并提供数据对应的行为。Java有API文档,里面有大量写好的对象,有需要直接查找调用就行。
理解封装的好处
让编程变得简单,有什么事,找对象,调用方法就行。
降低我们的学习成本。
private关键字
是一个权限修饰符。
可以修饰成员(成员变量和成员方法)。
被private修饰的成员只能在本类中才能访问。
针对每一个私有化的成员变量,都要提供get和set方法。
set方法:给成员变量赋值,方法用public修饰。
get方法:对外提供成员变量的值,方法用public修饰。
在setage()方法中可以对成员变量经行if语句判断,在setGender()中判断性别。
3.就近原则和this关键字
如下代码所示,setName()中name为局部变量的值,也就是方法体中的值(就近原则),而this.name则为成员变量中的值。
import java.util.Objects;
public class GirlFriend {
//成员变量
private String name;
private int age;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
//局部变量
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>=18&&age<=50){
this.age = age;
}else {
System.out.println("非法数据");
}
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
if(Objects.equals(gender, "女")){
this.gender = gender;
}else {
System.out.println("滚");
}
}
}
测试类
public class GirlFriendText {
public static void main(String[] args) {
GirlFriend gf1=new GirlFriend();
gf1.setName("小丹丹");
gf1.setAge(18);
gf1.setGender("男");
System.out.println(gf1.getAge());
System.out.println(gf1.getGender());
}
}
4.构造方法
构造方法也叫作构造器、构造函数。
作用:在创建对象的时候给成员变量经行赋值的。
public class Student{
修饰符 类名(参数){
方法体;
}
}
特点:1.方法名与类名相同,大小写也要一致。
2.没有返回值类型,连void都没有。
3.没有具体的返回值(不能由return带回结果数据)
空参构造方法
初始值都为默认值。
public Student(){
}
带全部参数构造方法
public Student(String name,int age){
this.name=name;
this.agw=age;
}
构造方法执行时机
1.创建对象的时候由虚拟机调用,不能手动调用构造方法。
2.每创建一次对象,就会调用一次构造方法。
具体实例
public class Student {
private String name;
private int age;
public Student(){
System.out.println("看看我执行了吗");
}
public Student(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 class StudentTest {
public static void main(String[] args) {
//调用空参构造
Student S=new Student();
//调用带参构造
Student s=new Student("全聚德一级码师",23);
System.out.println(s.getName());
System.out.println(s.getAge());
}
}
执行结果如下:
看看我执行力吗
全聚德一级码师
23
构造方法的注意事项
构造方法定义
1.如果没有定义构造方法,系统将给出一个默认的无参数构造方法。
2.如果定义了构造方法,系统将不再提供默认构造方法。
构造方法的重载
1.带参构造方法,和无参构造方法,两者方法名相同,但参数不同,这叫做构造方法的重载。
推荐的使用方式
1.无论是否使用,都需要把带参和无参的构造方法写上。
构造方法概述
创建对象的时候,虚拟机会自动调用构造方法,作用是给成员变量进行初始化。
5.标准的javabean类
1.类名需要见名知意
2.成员变量使用private修饰
3.提供至少两个构造方法(无参和带参)
4.成员方法(提供每一个成员变量对应的setXxx()/getXxx(),如果还有其他行为,也需要写上)
public class User {
private String username;
private String password;
private String email;
private String gender;
private int age;
public User(){
}
public User(String username, String password, String email, String gender, int age) {
this.username = username;
this.password = password;
this.email = email;
this.gender = gender;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
idea有快捷键 alt+insert可快速生成构造方法setXxx()/getXxx()。
也可使用ptg插件一件生成。
6.基本数据类型和引用数据类
Java的数据类型只有两大类:8大基本数据类型与引用数据类型。其中基本数据类型又被称为值类型。
基本数据类型:6种数字类型(byte/short/int/long/float/double)、1种字符型(char)、1种布尔型(boolean)。
引用数据类型:类(Class)、接口(Interface)、数组(Array)。
除了以上的基本数据类型和引用数据类型,还有一些其他相关的数据类型,例如字符串类型String、枚举类型Enum,它们都是基于引用数据类型来实现的。
引用数据类型:参数传递时,以拷贝引用地址的方式传递给接收变量,而非复制整个数据本体。除八大基本数据类型之外的所有数据类型,都为引用数据类型。所有引用数据类型的默认值都为null。数据值是存储在其他空间中,自己空间存储的是地址值。(赋值给其他变量,赋的是地址值)
基本数据类型:数据值是存储在自己的空间中。(赋值给其他变量,也是赋的真实值)
7.成员和局部
成员变量:类中方法外的变量
有默认初始化值
堆内存
随着对象的创建而存在,随着对象的消失而消失
整个类中有效
局部变量:方法中的变量
没有,使用之前要完成赋值
栈内存
随着方法的调用而存在,随着方法运行结束而消失
当前方法中有效
8.总结
根据上文总体写一个程序
import java.util.Random;
public class Role {
private String name;
private int blood;
private char gender;
private String face;
String[] boyfaces={"风流倜他","气宇轩昂","一塌糊涂"};
String[] girlfaces={"亭亭玉立","沉鱼落雁","倾国倾城"};
String[] attacks_desc={
"%s使出我滴孩来,给%s老孩来了一脚",
"%s使出我甩你一脸葱,给%s脸甩了一机子"
};
String[] injureds_desc={
"结果%s退了半步毫发无伤",
"结果%s受了点内伤"
};
public Role() {
}
public Role(String name, int blood,char gender) {
this.name = name;
this.blood = blood;
this.gender=gender;
setFace(gender);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getBlood() {
return blood;
}
public void setBlood(int blood) {
this.blood = blood;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getFace() {
return face;
}
public void setFace(char gender) {
Random r=new Random();
if(gender =='男'){
int index=r.nextInt(boyfaces.length);
this.face=boyfaces[index];
} else if (gender=='女') {
int index=r.nextInt(girlfaces.length);
this.face=girlfaces[index];
}else {
this.face="不能看";
}
}
public void attack(Role role){
Random r=new Random();
int index=r.nextInt(attacks_desc.length);
String kungfu=attacks_desc[index];
System.out.printf(kungfu,this.getName(),role.getName());
System.out.println();
int hurt=r.nextInt(20)+1;
int remainBlood=role.getBlood()-hurt;
remainBlood= Math.max(remainBlood, 0);
role.setBlood(remainBlood);
if(remainBlood>=80){
System.out.printf(injureds_desc[0],role.getName());
System.out.println();
}else {
System.out.printf(injureds_desc[1],role.getName());
System.out.println();
}
// System.out.println(this.getName()+"举起拳头,打了"+role.getName()+"一下,造成了"+hurt+"点伤害,"+role.getName()+"还剩下了"+remainBlood+"点血");
}
public void showRoleInfo(){
System.out.println("姓名为:"+getName());
System.out.println("血量为:"+getBlood());
System.out.println("性别为:"+getGender());
System.out.println("长相为:"+getFace());
}
}
public class GameTest {
public static void main(String[] args) {
// Scanner scan=new Scanner(System.in);
Role r1=new Role("坤坤",100,'男');
Role r2=new Role("全聚德一级码师",100,'女');
r1.showRoleInfo();
r2.showRoleInfo();
while (true){
r1.attack(r2);
if(r2.getBlood()==0){
System.out.println(r1.getName()+"ko"+r2.getName());
break;
}
r2.attack(r1);
if(r1.getBlood()==0){
System.out.println(r2.getName()+"ko"+r1.getName());
break;
}
}
}
}
运行结果:
全聚德一级码师使出我甩你一脸葱,给坤坤脸甩了一机子
结果坤坤受了点内伤
坤坤使出我甩你一脸葱,给全聚德一级码师脸甩了一机子
结果全聚德一级码师受了点内伤
全聚德一级码师使出我甩你一脸葱,给坤坤脸甩了一机子
结果坤坤受了点内伤
坤坤使出我滴孩来,给全聚德一级码师老孩来了一脚
结果全聚德一级码师受了点内伤
坤坤ko全聚德一级码师