ï¼ä¸ï¼ 构造方法:
构造方法特点:
1:任何一个类的内部都至少要有一个构造方法。
2:如果一个类的内部没有显式定义一个构造方法,那么编译器会帮助我们提供生成一个默认的无参的空实现的构造方法。
3:构造方法的方法名字必须与所在的类的名字相同。
4:构造方法没有返回类型 既不是void 也不是 其他的任何的类型。什么都不写。
5:如果在某一个类的内部,显式的提供了任意一个构造方法,那么编译器将不再提供那个默认无参的空实现的构造方法。
6:构造方法同样也可以重载。参数列表不同的构造方法构成了构造方法的重载。
7:构造方法只能使用new 关键字调用。
构造方法的作用:对象进行初始化的。
创建对象是jvm 完成的,对象初始化通常在构造方法内完成。
构造方法是用来生成对象的???(不准确)
构造方法重载的意义:可以帮助我们创建对象的时候,更好的给不同的对象进行不同属性的初始化。
例:
面向过程:
//实现一场战斗
//阿基里斯 vs 赫克托
//每个英雄 赋值 初始血量 1000.
//每个英雄 伤害随机
//阿基里斯 damage[30-50] 暴击率30% 暴击加成 1.8倍
//赫克托 damage [20-40] 暴击率50% 暴击加成 2倍
//
//然后普通攻击和暴击要求不同的输出内容,输出本次伤害,和对方剩余的血量
//一人一刀互相伤害
//使用循环模拟两个人的一场战斗
//while
//最终输出结果。谁胜利了,剩余血量。
public class TestProcessBattle {
public static void main(String[] args) throws Exception{
TestProcessBattle battle = new TestProcessBattle();
battle.battle();
}
void battle()throws Exception{
int ajlsHp = 1000;
int hktHp = 1000;
final int AJLS_DAM_MIN = 30;
final int AJLS_DAM_MAX = 51;
final double AJLS_CRITICAL_PERCENT = 0.3;
final double AJLS_CRITICAL_DAM = 1.8;
final int HKT_DAM_MIN = 20;
final int HKT_DAM_MAX = 41;
final double HKT_CRITICAL_PERCENT = 0.5;
final double HKT_CRITICAL_DAM = 2;
//循环来实现互相伤害
// while(ajlsHp > 0 && hktHp > 0){
// }
while(true){
//先让赫克托攻击阿基里斯
//先计算本次的基本伤害值
int damage = getRandomNumber(HKT_DAM_MIN, HKT_DAM_MAX);
//再算是否产生暴击
boolean isCritical = isHappened(HKT_CRITICAL_PERCENT);
//根据是否产生暴击计算相应的伤害加成
if(isCritical){
damage *= HKT_CRITICAL_DAM;
}
//减血
ajlsHp -= damage;
if(ajlsHp <= 0){
ajlsHp = 0;
printBattleMsg(isCritical,damage,ajlsHp,"赫克托","阿基里斯");
break;
}
//输出攻击伤害结果以及对方剩余的血量
printBattleMsg(isCritical,damage,ajlsHp,"赫克托","阿基里斯");
Thread.sleep(200);
//阿基里斯按照上面的方式攻击赫克托
damage = getRandomNumber(AJLS_DAM_MIN, AJLS_DAM_MAX);
//再算是否产生暴击
isCritical = isHappened(AJLS_CRITICAL_PERCENT);
//根据是否产生暴击计算相应的伤害加成
if(isCritical){
damage *= AJLS_CRITICAL_DAM;
}
//减血
hktHp -= damage;
if(hktHp <= 0){
hktHp = 0;
printBattleMsg(isCritical,damage,hktHp,"阿基里斯","赫克托");
break;
}
//输出攻击伤害结果以及对方剩余的血量
printBattleMsg(isCritical,damage,hktHp,"阿基里斯","赫克托");
Thread.sleep(200);
}
//打印战斗结果
if(ajlsHp > 0){
System.out.println("阿基里斯 最后 获得了战斗的胜利!~");
}else{
System.out.println("赫克托 最后 获得了战斗的胜利!~");
}
}
/**
* 得到指定区间的随机数
* @param min 区间的最小值 包含
* @param max 区间的最大值 不包含
* @return min 到 max 的区间值
*/
int getRandomNumber(int min,int max){
return (int)(Math.random()*(max-min)+min);
}
boolean isHappened(double percent){
return Math.random() < percent;
}
void printBattleMsg(boolean isCritical,int damage, int hp,String atkName,String atkedName){
if(isCritical){
System.out.println(atkName+" 【暴力攻击】了 "+atkedName +" ,造成了:【"+damage + "】点伤害!"+atkedName +" 剩余生命 : "+hp);
}else{
System.out.println(atkName+" 【攻击】了 "+atkedName +" ,造成了:【"+damage + "】点伤害!"+atkedName +" 剩余生命 : "+hp);
}
}
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
面向对象:
//实现一场战斗
//阿基里斯 vs 赫克托
//每个英雄 赋值 初始血量 1000.
//每个英雄 伤害随机
//阿基里斯 damage[30-50] 暴击率30% 暴击加成 1.8倍
//赫克托 damage [20-40] 暴击率50% 暴击加成 2倍
//
//然后普通攻击和暴击要求不同的输出内容,输出本次伤害,和对方剩余的血量
//一人一刀互相伤害
//使用循环模拟两个人的一场战斗
//while
//最终输出结果。谁胜利了,剩余血量。
//分析: 两个对象
//功能:攻击 属性:hp,基础攻击力的区间 暴击率 暴击加成。名字
//使用类描述对象:
//描述 一场战斗的 类 属性:参与者,功能:初始化战斗,开始战斗 战斗结束
public class TestOopBattle {
public static void main(String[] args) throws Exception{
Battle battle = new Battle();//构造方法--构造器--类的实例化
battle.initBattle();
battle.startBattle();
battle.endBattle();
}
}
//描述一场战斗的类
class Battle{
Warrior ajls;
Warrior hkt;
//初始化两个参与战斗的人
void initBattle(){
ajls = new Warrior("阿基里斯",1000,30,51,0.3,1.8);
// ajls.hp =1000;
// ajls.atkMin = 30;
// ajls.atkMax = 51;
// ajls.criticalPercent = 0.3;
// ajls.criticalDamage = 1.8;
// ajls.name = "阿基里斯";
hkt = new Warrior("赫克托",1000,20,41,0.5,2.0);
// hkt.hp =1000;
// hkt.atkMin = 20;
// hkt.atkMax = 41;
// hkt.criticalPercent = 0.5;
// hkt.criticalDamage = 2.0;
// hkt.name = "赫克托";
}
/**
* 开始战斗
*/
void startBattle()throws Exception{
while(true){
Thread.sleep(200);
boolean result = hkt.attack(ajls);
if(result){
return;
}
Thread.sleep(200);
result = ajls.attack(hkt);
if(result){
return;
}
}
}
void endBattle(){
if(ajls.hp > 0){
System.out.println(ajls.name + "获得了胜利!");
}else{
System.out.println(hkt.name + "获得了胜利!");
}
}
}
//描述战士的类
class Warrior{
//战士的属性
String name;
int hp;
int atkMin;
int atkMax;
double criticalPercent;
double criticalDamage;
public Warrior() {
}
public Warrior(String _name, int _hp,int _atkMin ,int _atkMax,double _criticalPercent,double _criticalDamage){
name = _name;
hp = _hp;
atkMax = _atkMax;
atkMin = _atkMin;
criticalDamage = _criticalDamage;
criticalPercent = _criticalPercent;
}
/**
* 描述战士攻击一次另外一个战士的过程。
* @param warrior 被攻击的战士
* @return 如果 warrior 被KO 了 那么返回true,否则返回false。
*/
boolean attack(Warrior warrior){
//先计算 伤害
int damage = getRandomNumber(atkMin, atkMax);
//计算是否暴击
boolean isCritical = isHappened(criticalPercent);
//伤害加成
if(isCritical){
damage *= criticalDamage;
}
//对方减血
warrior.hp -= damage;
if(warrior.hp <= 0){
warrior.hp = 0;
if(isCritical){
System.out.println(name + "【暴力攻击】"+warrior.name+"\t造成了 "+damage+"点伤害,\t"+warrior.name+"剩余血量为 = "+warrior.hp);
}else{
System.out.println(name + "【攻击】"+warrior.name+"\t造成了 "+damage+"点伤害,\t"+warrior.name+"剩余血量为 = "+warrior.hp);
}
return true;
}
//输出
if(isCritical){
System.out.println(name + "【暴力攻击】"+warrior.name+"\t造成了 "+damage+"点伤害,\t"+warrior.name+"剩余血量为 = "+warrior.hp);
}else{
System.out.println(name + "【攻击】"+warrior.name+"\t造成了 "+damage+"点伤害,\t"+warrior.name+"剩余血量为 = "+warrior.hp);
}
return false;
}
int getRandomNumber(int min,int max){
return (int)(Math.random()*(max-min)+min);
}
boolean isHappened(double percent){
return Math.random() < percent;
}
}
(二)内存分析图
//创建了一个Tree 类型的对象。
//tree 对象变量、对象引用
//Tree():构造方法 构造器
//类的实例化
Tree tree = new Tree();
//通过对象变量,对象引用来访问对象的功能。 通过. 点引用符来调用对象的功能。
//也可以通过点 . 引用符 来访问对象的自身的属性。
tree.show();
例:
//定义一个学生类:描述学生,属性,年龄,age,分数score,名字 String name,性别 String gender
//然后定义默认无参的构造方法,并对所有的属性 进行初始化
//然后定义带参数的构造方法,四个参数,对所有的属性通过参数赋值。
//然后定义 一个成员方法 show 展示学生的属性的。
//定义测试类,生成两个学生对象,一个调用默认无参的构造方法,一个调用 带参数的构造方法
//然后分别调用 show 方法。
public class TestStudent {
public static void main(String[] args) {
Student student = new Student();
Student student2 = new Student(12, 98, "rose", "女");
student.show();
student2.show();
}
}
class Student{
int age;
int score;
String name;
String gender;
public Student() {
age = 10;
score = 99;
name = "小红";
gender = "女";
}
public Student(int _age, int _score, String _name, String _gender) {
age = _age;
score = _score;
name = _name;
gender = _gender;
}
void show(){
System.out.println("name = "+name + "\tgender = "+gender + "\tage = "+age + "\tscore = "+score);
}
}
(三)java源文件
一个 .java源文件中可以定义多个类。
但是一个java 源文件中最多只能有一个使用public 修饰的类。
如果一个类中包含了一个public 修饰的类,那么该源文件的名字必须与该类同名。
当然一个java源文件中的所有的类,都可以不是用public 修饰的。
(四)局部变量 和 成员变量的 异同:
1:相同点:
变量的类型 都是 java 支持的任意的类型。
命名规范一致。
2:不同点:
作用域不同,局部的在方法内部,成员的在类的所有的方法中都可以访问(整个类)。
定义的位置不同:局部在方法中,成员在类的内部,方法的外部
局部变量必须先定义后使用。 成员变量只声明即可(jvm 会进行默认初始化)。
局部变量在栈中分配空间,成员在堆中分配空间。
局部变量的生命周期随着方法的返回而被自动回收。成员变量的的生命周期依赖于所在的对象。对象被回收了,那么成员变量的内存就被回收了。
优先级不同,局部变量被访问的优先级高于成员的。
在类中的方法中,实现某些功能,能用局部变量实现的尽量使用局部变量实现。
ï¼äºï¼ 对象数组
例:
//需求:定义一个学生类 Student 属性:age ,name,gender,score。
//定义两个构造方法,一个无参默认的,一个带参数的,通过参数给所有的成员变量赋值。
//Student类的功能:show 方法,展示属性的。study 方法,在方法中修改分数的属性。
//定义入口测试类,在main 中,定义Student类型的数组,长度为7,动态初始化。然后将数组的每一个元素打印。
//然后为每一个元素初始化(实例化)。并依次调用类中的方法。show study。
public class TestObjectArray {
public static void main(String[] args) {
Student[] students = new Student[7];
for (Student student : students) {
System.out.println(student);//null
}
String[] names = {"小刚","小明","小红","小马","小张","静静","小杨","小江","小花","小翠"};
String[] genders = {"男","男","女","男","男","女","男","男","女","女"};
for (int i = 0; i < students.length; i++) {
int age = getRandomNumber(18,30);
int index = getRandomNumber(0, names.length);
String name = names[index];
String gender = genders[index];
int score = getRandomNumber(60, 101);
students[i] = new Student(age, name, gender, score);
students[i].study();
students[i].show();
}
}
static int getRandomNumber(int min,int max){
return (int)(Math.random()*(max-min)+min);
}
}
class Student{
int age = 10;
String name;
String gender;
int score;
public Student() {
}
public Student(int _age, String _name, String _gender, int _score) {
age = _age;
name = _name;
gender = _gender;
score = _score;
}
void study(){
score += 5;
if(score > 100){
score = 100;
}
}
void show(){
System.out.println("name = "+name + "\tgender = "+gender + "\tage = "+age + "\tscore = "+score);
}
}
内存图:
ï¼å ï¼ 关键字:
1. package:
package:包的意思。
如果我们的java 源代码被放到了某个包(可以是n层的目录)下,那么源代码的第一句必须使用关键字 package 后面跟当前源文件所在的包的全路径名。目录之间使用.分隔。
比如:
HelloWorld.java 在 src.com.bjsxt.helloworld 目录下
package com.bjsxt.helloworld;
将不同的类放置到不同的包中的意义即分包管理类的意义:
1:不同的功能模块放置到不同的包中。方便由不同的人来负责管理维护。
2:可能不同的人写了同名的类,或者是不同的公司写了同名的类。
保证同名的类在不同的包下,不会冲突。
2. import:
import:java 的一个关键字。
作用:如果我们想在当前的类中访问其他包的某些类。
那么可以通过类所在的包的 全路径名+类名的方式访问。
java 提供了一种更为简便的方式,即使用import 在 package 语句和class 中间,将需要跨包访问的类,声明导入即可。
再使用相关的类的时候,就不需要写明 类的全路径名+类名 的形式。直接书写类名即可。
如果本包的类和跨包访问的类的类名冲突,那么优先访问本包的类,跨包的不能再使用import 导入的方式进行简易访问。
存在语义冲突时,只能使用包名+类名的方式访问跨包同名类。
jdk 提供了很多的类库供我们快速开始使用。
java.lang.*; 是 java 的核心包,该包中的所有的类被默认导入。如Math,System,Object都在这个包里。
java 中 包名+类名 才是一个类的唯一的标识