文章目录
java学习日志&head first java 源码
本人菜鸡,初学编程,写此文章大部分是为了尝鲜试玩,其次为了巩固学习效果,不妥之处还请多多指教。
正式的官方话相信在教材里已经看多了,我就用交流式的大白话来讲了。
首先我是找了一本书来看,网上据说比较经典的书籍有:head first java effective java think in java等等,我搞了本二手head first java😂
平台搭建
首先是下载好编译运行平台可以是编译器或者IDE
关于如何安装以及配置jdk环境
下载jdk,下面是链接
https://www.oracle.com/cn/java/technologies/javase-downloads.html#JDK15
不过据说使用最多的是jdk8,这个就够用了,当然装得高一点版本逼格更高,所以你懂的.
https://www.bilibili.com/video/BV18E41177zQ/?spm_id_from=333.788.videocard.1
这是我发现的比较讲得比较好的up主,用他的方法可以实现安装及配置,但是其他人的方法就稍微复杂一点点,也不知道为什么.
其他方法:
- 下载完以后,选择一个目录解压或者是安装,这个目录要记清楚,后面要用.
- 还是看视频吧,视频已经很清楚了,如下链接
https://www.bilibili.com/video/BV1U7411z7ut?from=search&seid=17498585928234631806
最后验证是否成功
win+R
输入cmd
输入java -version
如果出现版本信息,表明配置成功
如果失败了,调整前面的配置,然后要重新启动cmd命令,而不是在原有的cmd里面输入 java -version
开始第一行代码
书上说,IDE会隐藏一些细节,最好从命令列开始学习,等到你真正的了解内部运作之后再靠工具来提升生产力. 大家真正在工作中开发 java 应用都会使用eclipse,myeclipse, IntelliJ等等
不过依然值得花10分钟学习如何使用最原始的命令行格式编译和执行java 程序
下面我们来使用最原始的命令行方式来执行Hello World
- 首先创建一个文件夹,用来存放java源代码,比如说我在d盘建一个
这里面有好几个子文件夹,没有关系,你要简单点也可以的. - 然后创建第一个java 源文件
在屏幕空白位置,点击鼠标右键->新建->文本文件 得到一个文件”新建 文本文档.txt“
右键该文件->重命名为 HelloWorld.java
在该文件中敲入如下代码
public class HelloWorld{
public static void main(String[] args){
System.out.println("hello world");
}
}
因为java 是面向对象的编程语言,所以我们实际上是在创建一个个的类
class HelloWorld 表示这个类的名字是HelloWorld
public static void main(String[] args) 这是主方法,所有代码的入口
类似于c语言 ,相当于 _main 程序入口
System.out.println(“hello world”); 表示在控制台(黑屏幕)输出一个字符串“hello world”
.java 文件是java的源文件,但是不能直接运行,必须先被编译成为.class文件 才能够执行
java 使用 javac命令进行编译
语法:
javac filename.java
注:必须跟上.java 后缀名
如图 执行如下命令:
运行 win+r,输入 cmd 进入控制台界面
d: 切换盘符为d盘(因为我是放在d里面的,如果你要放在别的里面,那就打开对应的盘符)
cd D:\programming\project\source 切换目录到源文件目录(cd即为打开,而文件目录可以点击复制上来)
javac HelloWorld.java 编译命令 javac 文件名大小写必须一致
如果得到一行空白,就表示成功了,并且得到一个class文件: HelloWorld.class
注: 第一行切换盘符的e:不要忘记了
java的运行命令是
java classname
如图 执行如下命令:
运行 win+r,输入 cmd 进入控制台界面
e: 切换盘符为e盘
cd D:\programming\project\source 切换目录到源文件目录
java HelloWorld
注意大小写需要一致,并且没有后缀名.class
运行成功后会看到字符串 “hello world”
大功告成,万古不变的HelloWorld!
java所有的代码都是运行在类里面的
public class HelloWorld
public 表示这是一个可以公开访问的类
class 表示这是一个类
HelloWorld 表示类的名字,每个单词的首字母大写
public static void main(String[] args)
你会写很多代码,总有第一行执行的代码,这就是主方法
args 表示运行参数,在本例中没有使用到。
System.out.println(“hello world”);
会在控制台输出字符串
println 表示打印数据到控制台,并且换行
如何下载并且使用eclipse
直接下载就是最新版本,不过以前的某些版本会更流行以及稳定,有些竞赛会有版本要求,所以你可以先熟悉那个指定版本。比如我是Eclipse-java-2020-06
然后选择相应的个人版,以及相对应的系统。
然后就是安装,会让你选择一个workspace,就是用来存储你创建的项目的地方。
设计真正的程序
依次点击左上角“file” “new” “java project”
鼠标右键点击source创建一个新的类
再就是输入代码,举个栗子:
public class count {
public static void main(String[] args) {
// TODO Auto-generated method stub
int beernum=99;
String word="bottles";
while(beernum>0) {
if(beernum==1) {
word="bottles";
}
System.out.println(beernum+" "+word+" of beer on the wall");
System.out.println(beernum+" "+word+" of beer.");
System.out.println("take one down.");
System.out.println("pass it around.");
beernum--;
if(beernum>0) {
System.out.println(beernum+" "+word+" of beer on the wall");
}else {
System.out.println("no more bottles of beer on the wall");
}//else finished
}//while finished
}//mian method finished
}//class finished
点击就可以运行啦,如上是一个数酒瓶子的程序,从99加到0。
进入对象村
有人告诉我那里遍地都是对象。
先大概描述一下吧,直到我理解的更加深刻为止。
对象就好像通讯录里的一笔数据
通讯录的每张卡片都有相同的空白字段(实例变量)。填入新的联络人就如同创建新的实例(对象),填入卡片的数据代表联络人的状态。
在这个卡片类上的方法就是你会对卡片作的事情:getTel()、changeAddress()、deleteCard()等。
举个栗子
创建与测试Movie对象
源码:
public class Movie {
String title;
String genre;
int rating;
void playIt() {
System.out.println("Playing the movie");
}
}
public class MovieTestDrive{
public static void main(String[] args) {
Movie one =new Movie();
one.title="Gone with the Stock";
one.genre= "Tragic";
one.rating=-2;
Movie two=new Movie();
two.title="lost in cubicle space";
two.genre="comedy";
two.rating=5;
two.playIt();
Movie three=new Movie();
three.title="byte club";
three.genre="Tragic but ultimately uplifting";
three.rating=127;
}
}
快离开main!
只要还呆在main()中,你就是在对象村外。
main()的两种用途:
- 测试真正的类
- 启动你的java应用程序
开始第一个小游戏
猜数字游戏
摘要:
这个游戏涉及到game与player两个对象。game会产生介于0~9之间的随机数字,而3个player对象会猜测该数字(你可能觉得很无聊,但是目前你还只能做出这样的游戏,想要提升那就赶紧学习变强吧!)
程序源码:
package guessnumber;
public class Player {
int number = 0;//the number to be guessed
public void guess() {
number = (int)(Math.random()*10);
System.out.println("I'm guessing "+number);
}
}
package guessnumber;
public class GameLauncher {
public static void main(String[] args) {
// TODO Auto-generated method stub
GuessGame game=new GuessGame();
game.startGame();
}
}
package guessnumber;
public class GuessGame {
Player p1;
Player p2;
Player p3;
public void startGame() {
p1=new Player();
p2=new Player();
p3=new Player();
int guessp1 = 0;
int guessp2= 0;
int guessp3 = 0;
boolean p1isRight=false;
boolean p2isRight=false;
boolean p3isRight=false;
int targetNumber = (int)(Math.random()*10);
System.out.println("I'm thinking of a number between 0 and 9");
while(true) {
System.out.println("Number to guess is "+targetNumber);
p1.guess();
p2.guess();
p3.guess();
guessp1=p1.number;
System.out.println("player one guessed "+guessp1);
guessp2=p2.number;
System.out.println("player two guessed "+guessp2);
guessp3=p3.number;
System.out.println("player three guessed "+guessp3);
if(guessp1==targetNumber) {
p1isRight=true;
}
if(guessp2==targetNumber) {
p2isRight=true;
}
if(guessp3==targetNumber) {
p3isRight=true;
}
if(p1isRight||p2isRight||p3isRight) {
System.out.println("we have a winner!");
System.out.println("player one got it right?"+p1isRight);
System.out.println("player two got it right?!"+p2isRight);
System.out.println("player three got it right?!"+p3isRight);
System.out.println("game is over.");
break;//game is over
}else {
//no one is right ,so we have to continue
System.out.println("players will have to try again.");
}//if/else finished
}//loop finished
}//method finished
}//class finished
创建一个包,分别创建三个类,每个类名字要求与类名一致。
是我多次一举了,没必要分多个类来运行程序,直接类前面不加public 可以在一块使用
package sort;
public class DrumKitTestDrive {
public static void main(String[] args) {
// TODO Auto-generated method stub
DrumKit d = new DrumKit();
d.playSnare();
d.snare=false;
if(d.snare==true) {
d.playSnare();
}
d.playTopHat();
}
}
class DrumKit {
boolean topHat = true;
boolean snare = true;
void playSnare() {
System.out.println("bang bang ba-bang");
}
void playTopHat() {
System.out.println("ding ding da-ding");
}
}
primitive主数据类型和引用
java很注重类型,你无法把长颈鹿类型的变量装进兔子类型的变量当中。
变量就像是杯子,是一种容器,承载某些事物。
无法用小杯子装大值,反过来是可以的。
primitive主数据类型命名
- 名称必须以字母、下划线或者$符号开头,不能用数字开头。
- 除了第一个字符之外,后面就可以用数字。反正不要用在第一个字符就行。
- 只要符合上述两条规则,你就可以随意地命名,但还得要避开Java保留字。
引用对象
- 事实上没有对象变量这样的东西存在
- 只有引用(reference)到对象的变量
- 对象引用变量保存的是存取对象的方法
- 它不是对象的容器,而是类似指向对象的指针。或者可以说是地址。
Dog d=new Dog();
d.bark();
把Dog的引用变量想成是Dog的遥控器。你可以通过它来执行工作。
数组
数组犹如杯架
声明一个int数组变量。数组变量是数组对象的遥控器。
int[]nums;
创建大小为7的数组,并将它赋值给之前声明为int[]的变量nums。
nums=new int [7];
赋予int数组的每一个元素一个int值。要记得在int数组中的每一个元素皆为int类型的变量。
nums[0]=68;
nums[1]=69;
nums[2]=64;
nums[3]=66;
nums[4]=63;
nums[5]=65;
nums[6]=62;
数组也是对象
Dog的范例
public class Dog {
String name;
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog1=new Dog();
dog1.bark();
dog1.name="Bart";
Dog[]myDogs=new Dog[3];
myDogs[0]=new Dog();
myDogs[1]=new Dog();
myDogs[2]=dog1;
myDogs[0].name="Fred";
myDogs[1].name ="Marge";
System.out.print("last dog's name is ");
System.out.println(myDogs[2].name);
int x=0;
while(x<myDogs.length) {
myDogs[x].bark();
x=x+1;
}
}
public void bark() {
System.out.println(name + " says Ruff!");
}
public void eat() {
}
public void chaseCat() {}
}
输出:
null says Ruff!
last dog’s name is Bart
Fred says Ruff!
Marge says Ruff!
Bart says Ruff!
排排看源码
public class TestArrays {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[]index=new int[4];
index[0]=1;
index[1]=3;
index[2]=0;
index[3]=2;
String[]islands=new String[4];
islands[0]="Bermuda";
islands[1]= "Fiji";
islands[2] = "Azores";
islands[3] = "Cozumel";
int y = 0;
int ref;
while(y<4) {
ref = index[y];
System.out.print("island = ");
System.out.println(islands[ref]);
y =y+1;
}
}
}
island = Fiji
island = Cozumel
island = Bermuda
island = Azores
课后练习源码
迷宫源码
package migon;
public class Triangle {
double area;
int height;
int length;
public static void main(String[] args) {
// TODO Auto-generated method stub
int x=0;
Triangle[]ta = new Triangle[4];
while(x<4) {
ta[x]=new Triangle();
ta[x].height=(x+1)*2;
ta[x].length=x+4;
ta[x].setArea();
System.out.print("triangle"
+x+ ",area");
System.out.println(" = "+ta[x].area);
x=x+1;
}
int y=x;
x = 27;
Triangle t5 = ta[2];
ta[2].area=343;
System.out.print("y ="+y);
System.out.println(",t5 area = "+t5.area);
}
void setArea() {
area = (height*length)/2;
}
}
方法操作实例变量
类是对象的蓝图。意思是在编写类时,你是在描述java虚拟机应该如何制作该类型的对象。
任一类的每个实例变量都赛有相同的方法,但是方法可以根据实例变量的值来表现不同的行为。
可以传值给方法,方法会运用形参。调用的一方会传入实参。
也可以从方法中取回返回值;如果将一个方法声明有返回值,你就必须返回所声明类型的值。
eg:
int theSecret = life.giveSecret();
int giveSecret(){
return 42;
}
可以向方法中传入一个以上的参数,以逗号分开声明。
void go(){
TestStuff t = new TestStuff();
t.takeTwo(12,34);
}
void takeTwo(int x,int y){
int z = x+y;
System.out.println("Total is "+z);
}
Java是通过值传递的,也就是说通过拷贝传递。所以方法无法改变调用方法所传入的参数
封装encapsulation
可以起到保护数据的作用,限制数据的修改在一个合理的范围。
将实例变量标记为private,将getter与setter标记为public。这样的话实例变量就不可以直接存取,而要通过方法来改变,可以在方法处设置限制条件,以限制数据修改的范围。
封装GoodDog
package fengzhuang;
class GoodDog {//封装GoodDog
public int calcArea(int height,int width) {
return height*width;
}
private int size;
public int getSize() {
return size;
}
public void setSize(int s) {
if(s>20) {//限制条件
size = s;
}else {
;//占位无实际意义
}
}
void bark() {
if(size>60) {
System.out.println("Wooof!Wooof!");
}else if (size>14) {
System.out.println("Ruff! Ruff!");
}else {
System.out.println("Yip! Yip!");
}
}
}
public class GoofDogTestDrive {
public static void main(String[] args) {
// TODO Auto-generated method stub
//验证猜想
GoodDog three = new GoodDog();
int a=three.calcArea(7,12);
System.out.println("a= "+a);
System.out.println("a= "+three.calcArea(6,12));
//
GoodDog one = new GoodDog();
one.getSize();
one.setSize(70);
GoodDog two = new GoodDog();
two.setSize(8);
System.out.println("Dog one:"+one.getSize());
System.out.println("Dog two:"+two.getSize());
//变量的比较(primitive主数据类型或引用)
one.bark();
two.bark();
if(one==two) {System.out.print("true");}else {
System.out.println("false");//判断两个引用是否都指向同一对象
}
}
}
实例变量需要声明和初始化,实例变量永远有默认值。
局部变量没有默认值,如果在其被初始前就要使用的话,编译器会显示错误。
实例变量是声明在类内而不是方法内,局部变量是声明在方法中的。
编写程序
Sink a DotCom游戏
详情请看书本内容,这里吧源码复制上来了,是我纯手打1个小时的结果,感动了自己
import java.util.*;
public class DotCom {
private ArrayList<String>locationCells;
private String name;
public void setLocationCells(ArrayList<String>loc) {
locationCells = loc;
}
public void setName(String n) {
name = n;
}
public String checkYourself(String userInput) {
String result = "miss";
int index = locationCells.indexOf(userInput);
if(index>=0) {
locationCells.remove(index);
if(locationCells.isEmpty()) {
result = "kill";
System.out.println("Ouch! you sunk"+name +":(");
}else {
result = "hit";
}//close if
}//close if
return result;
}//close method
}//close class
```java
import java.util.*;
public class DotComBust {
private GameHelper helper = new GameHelper();
private ArrayList<DotCom>dotComsList = new ArrayList<DotCom>();
private int numOfGuesses = 0;
private void setUpGame() {
//first make some dot coms and give them locations
DotCom one = new DotCom();
one.setName("Pets.com");
DotCom two = new DotCom();
two.setName("eToys.com");
DotCom three = new DotCom();
three.setName("Go2.com");
dotComsList.add(one);
dotComsList.add(two);
dotComsList.add(three);
System.out.println("Your goal is to sink three dot coms.");
System.out.println("Pets.com,eToys.com,Go2.com");
System.out.println("Try to sink them all in the fewest number of guesses");
for(DotCom dotComToSet : dotComsList) {
ArrayList<String>newLocation = helper.placeDotCom(3);
dotComToSet.setLocationCells(newLocation);
}//close for loop
}//close setUpgame method
private void startPlaying() {
while(!dotComsList.isEmpty()) {
String userGuess = helper.getUserInput("Enter a guess");
checkUserGuess(userGuess);
}//close while
finishGame();
}//close startPlaying method
private void checkUserGuess(String userGuess) {
numOfGuesses++;
String result = "miss";
for(DotCom dotComToTest : dotComsList) {
result = dotComToTest.checkYourself(userGuess);
if(result.equals("hit")) {
break;
}
if(result.equals("kill")) {
dotComsList.remove(dotComToTest);
break;
}
}//close for
System.out.println(result);
}//close method
private void finishGame() {
System.out.println("All Dot coms are dead! your stock is now worthless.");
if(numOfGuesses<=18) {
System.out.println("it only took you"+numOfGuesses+"guesses.");
System.out.println("you got out before your options sank.");
}else {
System.out.println("took you long enough."+numOfGuesses+"guesses.");
System.out.println("Fish are dancing with your options");
}
}//close method
public static void main(String[] args) {
// TODO Auto-generated method stub
DotComBust game = new DotComBust();
game.setUpGame();
game.startPlaying();
}//close method
}
import java.io.*;
import java.util.*;
public class GameHelper {
private static final String alphabet = "abcdefg";
private int gridLength = 7;
private int gridSize = 49;
private int[]grid = new int[gridSize];
private int comCount = 0;
public String getUserInput(String prompt) {
String inputLine = null;
System.out.print(prompt +" ");
try {
BufferedReader is = new BufferedReader(
new InputStreamReader(System.in));
inputLine = is.readLine();
if(inputLine.length()==0) return null;
}catch (IOException e) {
System.out.println("IOException: "+e);
}
return inputLine.toLowerCase();
}
public ArrayList<String>placeDotCom(int comSize){
ArrayList<String>alphaCells = new ArrayList<String>();
String[]alphacoords = new String[comSize];
String temp = null;
int [] coords = new int[comSize];
int attempts = 0;
boolean success = false;
int location = 0;
comCount++;
int incr = 1;
if((comCount % 2)==1) {
incr = gridLength;
}
while(!success&attempts++<200) {
location = (int)(Math.random()*gridSize);
//System.out.print("try"+location);
int x=0;
success = true;
while (success && x<comSize) {
if(grid[location]==0) {
coords[x++]=location;
location+=incr;
if(location>=gridSize) {
success = false;
}
if(x>0 && (location % gridLength ==0)) {
success = false;
}
}else {
//System.out.print("used" +location);
success = false;
}
}
}
int x=0;
int row =0;
int column = 0;
//System.out.println("\n");
while (x<comSize) {
grid[coords[x]] = 1;
row = (int)(coords[x]/gridLength);
column = coords[x]%gridLength;
temp = String.valueOf(alphabet.charAt(column));
alphaCells.add(temp.concat(Integer.toString(row)));
x++;
//System.out.print("coord" +x+ "=" +alphaCells.get(x-1));
}
//System.out.println("\n");
return alphaCells;
}
}
分别创建三个类,可以完美运行。
关于for循环
基本的for循环
for(int i = o;i<100;i++){}
加强版的for循环
for(String name :nameArray){}
以中文来说就是“对nameArray中的每个元素执行一次”
继承与多态
继承
继承可以防止子类中出现重复的程序代码
次级类会自动获得父类的功能
子类还可以覆盖掉继承下来的方法,甚至加上新的方法。
当你调用对象引用的方法时,你会调用到与该对象类型最接近的方法。换句话说,最低阶的会胜出。
IS-A 测试适用在继承层次的任何地方。 可以通过这个测试意味着继承设计是对的。
多态
一般声明引用和创建对象的重点在于引用类型与对象的类型必须相符。但是在多态下,引用与对象可以是不同的类型。当你声明一个引用变量时,任何对该引用变量类型可通过IS-A测试的对象都可以被赋值给该引用。
源码
class Animals{
String name = "animal";
public void makenoise(){
System.out.println("this is animals");
}
public void roar() {
// TODO Auto-generated method stub
}
}
class Dogs extends Animals{
public void roar() {
System.out.println("wang wang!");
}
public void makenoise() {
System.out.println("this is dogs");
}
}
class Cats extends Animals{
public void roar() {
System.out.println("miao miao!");
}
}
class Birds extends Animals{
public void roar() {
System.out.println("zhi zhi!");
}
}
class Chickens extends Birds{
public void roar() {
System.out.println("gugugu!");
}
}
public class JichengTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dogs dog = new Dogs();
dog.makenoise();
dog.roar();
Animals pig = new Animals();
pig.makenoise();
Cats cat = new Cats();
cat.makenoise();
cat.roar();
System.out.println("the next try");
Animals[] animal = new Animals[4];
animal[0] = new Dogs();
animal[1] = new Cats();
animal[2] = new Birds();
animal[3] = new Chickens();
animal[0].makenoise();
animal[1].makenoise();
animal[2].makenoise();
animal[3].makenoise();
animal[0].roar();
animal[1].roar();
animal[2].roar();
animal[3].roar();
}
}