初学Java (不要再删了!!!)

前言

这是我学Java时的作业。大概用了半个月时间。之前写出来一篇篇放到QQ空间,现在总结到一块。内容很多,都是Java基础内容。有很多写好的代码。有个朋友请教Java内容。我就把作业给她看,备她使用,并一同学习。现在放到这里,也是一同学习的意思。发表自己的想法和学习内容,很爽的!

第一篇,试水作业。
第二篇
boolean数据类型用法
运算符【逻辑运算符、关系运算符、算术运算符】
优先级
if结构
if-else
if-else if-else if-.....-else
switch
嵌套if(){if(){}}


里面有一些代码。这些代码我有注释。


第三篇
循环结构,算术运算符的用法 while循环 do-while循环 for循环 break的使用
continue的用法 嵌套循环 日历程序的制作


第四篇
数组 常用算法 数组类型 键盘赋值 length属性 让用户自己定义数组长度
求数组中的最大值
数组的排序
数组算法
多维数组
简单的学生成绩管理程序


第五篇对象
类和对象
有参、无参、返回、不返回
成员变量
return和多参
toString的用法
this 的用法
封装
方法的重载
构造函数


第六篇
学生管理程序。


第七篇
详解学生管理系统。里面有一个记事本程序,是兵哥写的。


第八、九、十、十一、十二篇都是在讲这个学生管理系统


第十三篇
构造代码块
函数调用

第十四篇
main方法
静态工具类
一张Javase核心示意图。

《初学Java》系列之一


和同学在群里聊天,朋友问我最近干什么。我说刚看完一本书。寻思下一步干什么。他让我看《西游记》,我才不看。我确实不知道干什么。另外一个同学说,看Java吧。我想了想前途,1、开学要补考Java。2、Java学习资料比较齐全。老师有Java群放着很多作业文件。3、课本在书桌上放着。


好吧,那就学Java。颇有点儿不得已而为之的感觉。这个系列大概能够写到开学了。


我为什么挂科?因为我根本没有认真上过课......


现在我从第三章开始学。主要学习的是老师留下的文件。


顺序结构
交换两个整数x和y
public class test{
public static void main(String[] args){
int x=10,y=11,t;
System.out.printf("x,y交换前的值是:\n");
System.out.printf("x=%d\t y=%d\n",x,y);{
t=x;
x=y;
y=t;
}
}
}
看着可别扭,和壁虎老师教的不一样啊。写代码的习惯不一样。原理都是一样的,int声明三个整型变量xyt,然后赋值,然后交换,然后输出。
我真的是不习惯老师写代码的方式,没有壁虎老师写的好玩。
所以,我还是看视频跟着敲代码吧。


第三章运算符和条件结构


public class test{
public static void main(String[]args){
int A=45;
int B=78;
int t=A;A=B;B=t;
System.out.println("A的值为:"+A);
System.out.println("B的值为:"+B);
}
}
见鬼了。视频的效果比课本的效果好很多。看来这个代码要写十遍才行。
1、public class test{
public static void main(String[]args){
int a=4;
int b=3;
int t=a;a=b;b=t;//声明一个变量,变量名为t。t的值为a,然后又声明一个变量a,这时候赋值为b。然后之前那个a其实已经不存在,变成了t。然后再给b赋值为t,于是交换完成。
System.out.println("a的值为:"+a);
System.out.println("b的值为:"+b);
}
}
2、public class test{
public static void main(String[] args){
int a=4;b=3;
int t=a;a=b;b=t;
System.out.println("a为:"+a);
System.out.println("b为:"+b);
}
}
3、public class test{
public static void main(String[]args){
int a=4;b=3;//以前我不知道这个是声明变量的意思。现在知道int是变量的类型。a是变量名。=是把右边的数值赋值给左边。4是数值。有没有想过为什么要这样做?事前声明变量,后面的代码就可以直接使用。提高代码利用率。后面写一个日历的程序的时候,代码很多,变量声明的也多。在前面声明一次,后面就不必再声明了。
int t=a;a=b;b=a;
System.out.println("a为:"+a);
System.out.println("b为:"+b);//我没有运行代码进行验证。
}
}
4、public class test{
public static void main(String[] args){
int a=4;b=3;
int t=a;a=b;b=t;
System.out.println("a为:"+a);
System.out.println("b为:"+b);//框架、入口、内容。声明变量,输出。
}
}//文件名test要和文件一致。这些在eclipse中会有提醒。但是壁虎老师却让我们用记事本写代码。
5、public class test{
public static void main(String[] args){
int a=4;b=3;
int t=a;a=b;b=t;
System.out.println("a为:"+a);
System.out.println("b为:"+b);
}
}//刚才在(String[]args)后面加;不对,这个是入口,不用加的。
6、public class test{
public static void main(String[] args){
int a=4;b=3;
int t=a;a=b;b=t;
System.out.println("a为:"+a);
System.out.println("b为:"+b);
}
}


不写了。这让我想起来背英语了。一个单词念差不多一百遍了。但是没什么用,效果不好,用的时候还是忘记。今天到此结束吧。脑子都要炸掉了。


《初学Java》系列二


武断的开始胜过犹豫不决的寻找。
上午用掉三个小时学习第三章。竟也能学完。下午用了一个小时检查错误,觉得满意。今天主要知识点,


boolean数据类型用法
运算符【逻辑运算符、关系运算符、算术运算符】
优先级
if结构
if-else
if-else if-else if-.....-else
switch
嵌套if(){if(){}}


每个知识点都是有案例。


boolean的使用


boolean【布尔】类型,存储true或false。使用方法和int、double一样。都是数据类型。
public class test{
public static void main(String[] args){
int a=2;
int b=2;
boolean flag;
flag=a==b;
System.out.println(flag);
}
}


public class test{
public static void main(String[] args){
int a=2;
int b=2;
boolean=a!=b;
System.out.println(flag);
}
}


以上两个例子分别对应的是boolean的true和false,第一个运行结果是true,第二个运行结果是false。
写代码的时候,壁虎老师强调格式,要写的层次分明。


if条件结构


if(条件){
//语句
}
比如,if(令狐冲Java成绩>90){
师父奖励令狐冲;
}
在后面学习中,if和for经常嵌套使用。【for主要是循环语句使用。第四章的内容。】
import java.util.*;
public class test{
public static void main(String[] args){
Scanner in= new Scanner(System.in);
System.out.println("请输入成绩:");
int score=in.nextInt();
if(score>90){
System.out.println("师父有奖励");
}
System.out.println("面壁思过!");
}
}//import导入Java中的util包,里面有很多东西可用,目前用过的是scanner【扫描仪,可能说法不同。但是知道其中含义即可】和随机数【random】。*是包中所有内容。Scanner是扫描仪的意思,声明一个扫描仪,变量名为in。而new Scanner(System.in)意思是从系统中输入一个数据。【其实这个是面向对象的内容。现在我还不是很明白其中含义,好像是声明一个新对象然后用来调用。】后面的学习将会经常用到import java.util.*,声明之后,还要接受数据,接受数据之前要声明一个变量用于存储数据。在这里是声明int score=in.nextInt(),接受的是整型数据类型。【in.next()接受字符串。】
//还没有讲到if-else语句。后面章节中会讲到if-else和for语句。等到写日历程序的时候,if和for语句使用次数目不暇接。
两个例子不同之处,后者不必声明boolean。直接在if(){}中使用。true,执行{}里面的语句。false,执行{}外的语句。
语句变成这样if(scoer>90==flase){},如何解释?输入的成绩score>90为true,true==(恒等于)false为假,false执行{}外的语句。进行了两次判断。【这些都是老师讲解的内容。如果是看书,没有如此详细的写出判断思路。】


逻辑运算符
作用就是把多个条件连接起来。&&是同时“并”
||或,连个条件中一个条件为真。!“取反”,!ture变成了false。【!放在前面,刚开始使用时,我放到了后面。会报错。我明明写好,却不停报错,找不到原因,修改多次,手忙脚乱。】
import java.util.*;
public class test{
public static void main(String[] args){
Scanner in=Scanner(System.in);
System.out.println("请输入Java成绩:");
int java=in.nextInt();
System.out.println("请输入sql成绩:");
int sql=in.nextInt();
if(java>90&&sql>90){
System.out.println("给你一本独孤九剑");
}
System.out.println("面壁思过");
}
}//in.nextInt()是接受数据。之前声明了Scanner。为的就是接受输入的数据。


import java.util.*;
public class test{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.println("请输入Java成绩:");
int java=in.nextInt();
System.out.println("请输入sql成绩:");
int sql=in.nextInt();
if(!(java>90)&&sql>90){
System.out.println("奖励");
}
System.out.println("面壁思过!");
}
}//这个例子和上面例子不同。在于!(Java>90)&&sql>90,前面是取反,如果Java>90,!取反之后,就是假了。假&&真,还是假,执行{}之外的语句。


运算符优先级
一堆运算符同时出现,先执行谁,后执行谁?于是就有了优先级的问题。我记得应老师讲过关于加减乘除优先级的问题。解释了为什么先算乘法,后算加法。(http://mp.weixin.qq.com/s?__biz=MzI4ODYwNTM3Ng==&mid=2247483866&idx=1&sn=54bda8811c5e50263fc6ebe770c8d3a7&chksm=ec3a9475db4d1d63f0cb23a02d062547b49dfb04233d63abd8581b858f86b8bbd817bfd55579&mpshare=1&scene=23&srcid=02249P4Yal1HRWbiPoLGBu3T#rd
《从几何意义理解四则运算优先级》)


(!4>5&&5>4||4>3)运算符先后顺序,其中!是逻辑运算符,只能对boolean类型的数据进行操作,所以这个式子会报错。
(!(4>5)&&5>4||4>3)加了(),优先级就是()了,变为了boolean类型。能够!,!(4>5)是true,因为先是false然后取反,于是是true。之后,顺序是:>→&&→||


if-else
import java.util.*;
public class test{
public static void main(String[]args){
System.out.println("请输入你的成绩:");
Scanner in=new Scanner(System.in);
int score=in.nextInt();
if(score>90){
System.out.println("奖励");
}else{
System.out.println("面壁思过");
}
}
}//怎么解释呢?这是说,如果if后面的条件成立(为true),执行if后面的{},条件不成立(false),执行else{}语句。当然,用两个if也能使用。


多重if结构
题目,学员成绩评定。成绩>=90,优秀;80<成绩<90,良好;成绩<=80,差;
如何实现?
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请输入成绩:");
int score=in.nextInt();
if(score>90){
System.out.println("优秀");
}else if(score>80){
System.out.println("良好");
}else{
System.out.println("差");
}
}
}//if-else if-else if-......-else可以有很多条件。在写日历程序的时候,会用到,因为要判断月份。还要判断闰年和平年。


if嵌套结构
就是if中的if,大袋子套小袋子。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请输入性别(男/女)");
String sex=in.next();//第一次用到String,声明一个变量String。因为控制台接收的是字符串。
if(sex.equals("男")){
System.out.println("请输入年龄:");
int age=in.nextInt();
if(age>=18){
System.out.println("成年了。");
}else{
System.out.println("未成年");
}
}else if(sex.equals("女")){
System.out.println("请问姑娘芳龄几何?");
}else{
System.out.println("输入错误!世上只有男女两种性别。");
}
}
}//这里面使用了sex.equals("男")这里是面向对象的内容。


switch结构
switch是开关、判断的意思。题目:令狐冲参加武林大会,第一名,武林盟主。第二名武当掌门。第三名峨眉掌门。否则,逐出师门。
1、用if-else结构写。也可以用四个if实现。
2、用switch实现。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请输入名次:");
int mingci=in.nextInt();
if(){}
if(){}
if(){}
if(){}
}//里面内容不写就是判断名次123的关系。
}
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请输入名次:");
int mingci=in.nextInt();
switch(mingci){//switch(只能是int和char类型。其他不行的。double,boolean,String都是不行的。目前我只知道这集中数据类型。int是整型,char是字符类型。)
case1;//案例,case数量随意,但是一定要有常量int或者char表示的常量。这个以前没有注意到。
System.out.println("武林盟主");
break;//跳出

case2;
System.out.println("武当掌门");
break;


case3;
System.out.println("峨眉掌门");
break;//这里要解释的是break的作用,如果没有就要往后面执行。有它,就是跳出,不再执行。

default;//默认意思。
System.out.println("逐出师门");
}
}
}
如果int mingci=in.nextInt()变成了char会怎样?Scanner不能接受char类型的数据。
improt java.util.*和Scanner in=new Scanner(System.in)就没有用处了。
直接声明
char sex="男";
switch(sex){
case'男';
System.out.println("请进。");
break;

case1;
System.out.println("拒绝入内");
break;
}//主意char类型使用。




题目,用户输入一个数,判断奇偶性。(能被2整除的数就是偶数。)
import java.util.*;
public class test{
public static void main(String[] args){
Scanner in=new scanner(System.in);
System.out.println("请输入一个整数:");
int number=in.nextInt();
if(number=0){
System.out.println("请输入正整数。");
}else{
if(number%2==0){//取余数看看是不是等于0,为了判断是否为零。然后判断奇偶性。
System.out.println(number+"它是一个偶数");
}else{
System.out.println(number+"它是一个奇数");
}
}
}
}//记住要写注释。否则代码变长,检查时为难。


题目,求平年和闰年。(被4整除不能被100整除或者能被400整除就是闰年)
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);//声明一个扫描仪,用来接收数据。
System.out.println("请输入年份:");
int year=in.nextInt();//声明一个变量int,用来接收数据。
if(year%4==0&&year%100!=0||year%100==0){//判断闰年的条件。这个像是数学题。
System.out.println("它是一个闰年");
}else{
System.out.println("它是一个平年");
}


}
}//第三章后面要写一个日历的。代码的重复利用率提高,Java有这个好处,声明一次后面就能用了。


题目,取随机数。
import java.util.*;//random是随机数的函数,也在util这个包里面。
public class test{
public static void main(String[]args){
Random ww=new Random ();//声明一个随机数
int number=ww.nextInt(10)//声明一个变量,接受十个随机数
System.out.println("随机数为:"+number);
}
}


public class test{
public static void main(String[]args){
int number=((int)(Math.random()*10));//声明一个变量,并强制转换。据说这个办法可以支持多线程。
System.out.pringln(number);
}
}
题目,猜拳游戏。
首先分析题目内容。电脑和用户输入。
用户输入,电脑输入,然后判断。条件结构。
import java.util.*;
public class test{
public static void main(String[]args){
System.out.println("*猜拳游戏*");
System.out.println("请出拳:(1.剪刀 2.石头 3.布)");
Scanner in=new Scanner(System.in);
int person=in.nextInt();
int computer=(int)(Math.random()*3)+1;//四个要点,1、随机数 2.强制转换 3.数量为3,0~2之间 4.+1,目的是避免出现0.没有用
Random number=new Random();
int number1=number.nextInt(3);
if(person==computer){
System.out.println("平局");
}else if(person==1&&computer==2||person==2&&computer==3||person==3&&computer==1){
System.out.println("你输了。电脑出的是:"+computer);
}
else{
System.out.println("你赢了。电脑出的是:"+computer);//这样是嵌套结构。
}
}
}//加上switch,能够加进去char,说的不是数字


import java.util.*;//导入util包
public class test{//写框架,命名为test
public static void main(String[]args){//写入口,
System.out.println("*猜拳游戏*");//输出一句话用来提示
System.out.println("请出拳:(1.剪刀 2.石头 3.布)");
Scanner in=new Scanner(System.in);//声明一个扫描仪,用来接收数据。
int person=in.nextInt();//声明变量int接受数据,命名为person
int computer=(int)(Math.random()*3)+1;//声明一个变量用来接收电脑给出的随机数。
String Marks="拳头";//声明一个变量,用来标记。
String Marks1="拳头";
switch(person){//switch为的是改变marks的值。
case1;
Marks="剪刀";
break;
case2;
Marks="石头";
break;
case3;
Marks="布";
break;
}
switch(computer){//switch为的是改变marks的值。
case1;
Marks1="剪刀";
break;
case2;
Marks1="石头";
break;
case3;
Marks1="布";
break;
}
if(person==computer){//判断电脑和用户数值,并给出数值代表的含义
System.out.println("平局。你出的是:"+Marks+"电脑出的是:"+Marks1);
}else if(person==1&&computer==2||person==2&&computer==3||person==3&&computer==1){
System.out.println("你输了。你出的是:"+Marks+"电脑出的是:"+Marks1);
}
else{
System.out.println("你赢了。你出的是:"+Marks+"电脑出的是:"+Marks1);//这样是嵌套结构。
}
}
}//用户和电脑各自声明了一次String marks="haha"
switch只能接受int和char。所以没有直接用String,而是声明一个String。
//猜拳游戏分两次讲,于是写了两次代码。


注意,以上代码我并未运行检验。可能有错。年前敲过一遍,运行调试过。现在重看,懒的调试。




《初学Java》系列三


内容多。


第四章循环结构


算术运算符的用法


运算符分为一元、二元、三元。划分依据是根据操作数的不同而定。一元是对一个数值的操作。二元是对两个数值进行操作。三元运算符是个if结构啊。if(){}else{}


一元运算符,i++,先使用然后对自身+1,int i=1;int b=i++,显示的结果b=1,i=2.在赋值的时候,和i++不同。i是个变量名而已。没有什么特别的含义。等写案例的时候再体会。


while循环
先判断再执行。循环条件只能是boolean类型
int i=1;
while(i<=30){
System.out.println("我爱经济学");
}//和if不一样的是,if判断之后,决定是否执行。而while执行一次再判断。有一个返回判断的过程。




public class test{
public static void main(String[]args){
int i=1;
while(i<=10000){
System.out.println("我爱经济学"+i);
}
}
}//会有怎样的效果?陷入死循环!因为i根本没有变化。


public class test{
public static void main(String[]args){
int i=1;//声明一个变量。变量名为i,赋值为1
while(i<=10000){
System.out.println("I love economic"+i);
i++;//对自身+1,这样就有了一个条件。
}
System.out.println("嗯。这很好");//作为循环体结束后的输出。
}
}//注意,要先声明一个变量i,然后给循环条件。i++是为了避免死循环。


累加求和


循环三要素,1、循环初始化。【就是声明一个变量。】2、判断条件。【比如i<year】3、改变循环体中循环变量的值。【比如i++】
循环使用的条件,1、代码相似。2、重复使用。【或者操作内容相似。公式相似,数值不同,便用循环了。】
比如,1+2+3+...+100=?
public class test{
public static void main(String[]args){
int i=1;
int sum=0;//声明一个变量用来存储数值的和
while(i<=100){
sum=sum+i;//求和
i++;//自身+1,从1开始
}
System.out.println("1+2+3+...+100="+sum);
}//+是连接符的意思。
}


题目:求学员的平均成绩。
分析,1、录入学院成绩 2、累加求和。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);//声明一个扫描仪,用来输入成绩
System.out.println("请输入学生人数:");//这个是题目要求,学生成绩和学生人数相等。
int person=in.nextInt();//声明一个变量。用来接收上面的学生的人数这个数据。
int i=1;//声明一个变量,就是循环的初始值。
while(i<=person){
System.out.println("请输入第"+i+"个学员的成绩");//提示用户输入成绩。
int a=in.nextInt();//接受上一步输入的学生成绩。电脑只知道是数据。我有个感悟,声明一次Scanner后面要用,只要声明变量就可以使用。
int sum=sum+a;//求所有成绩的总和或求和所有输入的成绩。
i++;//改变循环变量的值,为了跳出循环体。
}
int avg=sum/person;
System.out.println(person+"个人的平均成绩为:"+avg);
}
}
//没有声明sum啊!在循环体重声明的变量是局部变量,只针对循环有用。出了循环体,后面没有。


import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);//声明一个扫描仪,用来输入成绩
System.out.println("请输入学生人数:");//这个是题目要求,学生成绩和学生人数相等。
int person=in.nextInt();//声明一个变量。用来接收上面的学生的人数这个数据。
int i=1;//声明一个变量,就是循环的初始值。
int sum=0;
while(i<=person){
System.out.println("请输入第"+i+"个学员的成绩");//提示用户输入成绩。
int a=in.nextInt();//接受上一步输入的学生成绩。电脑只知道是数据。我有个感悟,声明一次Scanner后面要用,只要声明变量就可以使用。
sum=sum+a;//求所有成绩的总和或求和所有输入的成绩。
i++;//改变循环变量的值,为了跳出循环体。
}
int avg=sum/person;
System.out.println(person+"个人的平均成绩为:"+avg);
}
}


注意。循环的三个要素,1、循环初始化。2、循环条件。3、改变循环体中变量的值。【我觉得后面很少用到while循环,而是经常用到for循环。】


题目:06年8万,哪一年达到二十万?增长率为25%
public class test{
public static void main(String[]args){
int year=2006;//声明一个变量,year,初始值为2006
int i=80000;
whlie(i<200000){
i=i+(i/100*25);
year++;//i的变量已经改变,不用这样变,反倒是改变year
}
System.out.println(year+"将达到二十万");
}//输出结果,告诉用户结果如何。
}


do-while结构
先循环后判断循环条件。
do{循环操作}while(条件)//至少要执行一次循环操作。和while循环的不同之处。


猜数字游戏。
1、电脑随机数 2、用户输入 3、比较电脑和用户数值大小。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
Random myrandom=new Random();//声明一个变量存储marandom
int a=myrandom.nextInt(101);//0~100是101个数,声明一个变量接受电脑随机数。
int number;//只有声明在外面后面才能用。但是没有赋值,只是在空间里划分了一块地方。并不能调用。只有赋值了才能调用。
do{
System.out.println("请猜数");
number=in.nextInt();//接受用户输入的数。int number是会报错的。因为已经在上面声明一次。不能重复声明。
if(number<a){
System.out.println("小了");
}else if(number>a){
System.out.println("大了");
}
}while(number!=a)//只要number不等于a,就是true,返回去执行循环体。
System.out.println("对了。");
}
}
//如果是用while,要注意给number初始化。没有赋值,不能调用。


先执行后判断,和先判断后执行,一个影响是声明的变量有没有初始化。


使用myeclipse
这个没有什么好讲的。学校老师用的是ediplus。


for循环
已知循环次数情况下使用。
for( ; ; ){循环操作}
比如for(int i=0;i<100;i++){}//1.循环初始化 2.循环条件 3.改变循环变量的值。避免死循环。4、循环内容。


题目:循环输入学生的5次成绩,求平均值。
壁虎老师说,初学者尽量用记事本,目的是增加对代码英文的熟悉程度。


import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);//声明一个扫描仪
int sum=0;//声明一个变量,用来存储总和
for(int j=0;j<5;j++)//声明一个初始变量,赋值为0,循环条件就<5,循环体变量改变j++{
System.out.println("请输入成绩:");//还可以写的更具体“请输入你的第”+(j+1)+"次成绩";//因为是j初始值为0,所以就要+1.现在回顾一元运算符,i++和++i的区别。i++是先使用,j=0,进入到循环体中,仍然是0。如果是++i,就不用这样做了。
int score=in.nextInt();//声明一个变量用来接收用户输入的数据。
sum=sum+score;//求和,总成绩。循环体外已经声明一次,现在不用声明了。
}
System.out.println("平均分为:"+sum/5);//这个是题目已知的条件,之前写过相似内容,可以声明一个变量,存储学生人数,用sum/person


}
}


import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请输入一个数");
int number=in.nextInt();
for(int i=0,j=number;i<=j;i++,j--){//声明了两个,一个是i,循环变量。一个是j,用来赋值number,即用户输入的值。
System.out.println(i+"+"+j+"="+(i+j));//1+2=3这样的效果。这个可以用来写九九乘法表。
}
}
}


public class test_1{
public static void main(String[] args){
System.out.println("--九九乘法表--");
for(int i=1;i<=9;i++){//声明一个变量,初始值为1,循环条件<=9,因为九九乘法表是这样的。改变循环变量值i++,i++是先使用,所以i的值是1
for(int j=1;j<=i;j++){//嵌套循环。大循环执行一次,小循环执行一遍。
System.out.print(j+"*"+i+"="+j*i+"\t");//1*1=1 \t是制表符。print没有换行,现在知道这个代码是横着执行的。以前以为是竖着执行。有了制表符,横着执行有了空隙。
}
System.out.println();//执行一遍,换行。
}
}
}


for与break结合
import java.util.Scanner;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
for(;;){
System.out.println("继续吗?");
String flag=in.next();
if(flag.equals("yes")){
System.out.println("好,继续吧。");
}else{
break;//结束循环。跳出的意思。
}
}
}
}


continue的用法
import java.util.*;
public class test{
public static void main(String[] args){
Scanner in=new Scanner(System.in);//声明一个扫描仪用来接收数据。
while(true){//这样就一直循环了。
System.out.println("请输入密码:");
int password=in.nextInt();//声明一个变量用来接收数据。
if(password!=123456){
continue;
}
break;//跳出循环。
System.out.println("没有的一句");//留着测试,永远不会执行。因为break跳出循环了。会报错的!只能删除的。
}
System.out.println("正确");
}
}
并没有用到continue,意思是很多循环,它跳出这次循环,执行下一个循环。因为没有例子。不容易理解。


嵌套循环


public class test{
public static void main(String[] args){
int i=1;//声明一个变量,初始值为1.
while(i<=7){//循环条件
int j=1;//声明一个变量,初始值为1
System.out.println("外出第"+j+"次");//输出开车第一次。
while(j<=3){
System.out.ptintln("坐车第"+j+"次");
j++;//改变循环变量的值。
}
i++;//改变大循环变量的值。
}//大循环循环一次,小循环循环一遍。一对三的关系。我想到的是后面日历的效果。一遍是直到跳出循环。
}
//我没有学会debug。


日历程序的制作


先上一段代码,这是一个很小的日历。输入年份和月份,日历就出来的。


import java.util.*;
public class test_2{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.println("请输入年份:");
int year=in.nextInt();
System.out.println("请输入月份:");
int month=in.nextInt();
int sum=0;
for(int i=1900;i<year;i++){
if(i%4==0&&i%100!=0||i%400==0){
sum+=366;
}else{
sum+=365;
}
}
for(int i=1;i<month;i++){
if(i==2){
if(year%400==0){
sum+=29;
}else{
sum+=28;
}}else{
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12){
sum+=31;
}else{
sum+=30;
}
}
}
int days=0;
if(month==2){
if(year%400==0){
sum+=29;
}else{
sum+=28;
}}else{
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
sum+=31;
}else{
sum+=30;
}
sum+=1;
int wekday=sum%7;
System.out.println("日\t一\t二\t三\t四\t五\t六");
for(int i=1;i<=wekday;i++){
System.out.print("\t");
}
for(int i=1;i<=30;i++){
if(sum%7==6){
System.out.print(i+"\n");
}else{
System.out.print(i+"\t");
}
sum++;
}
     }
  }
}
先对日历进行注释。真相往往不是我们看到的那样。


import java.util.*;//导入util包,用来声明Scanner。
public class test_2{//写框架,命名一致。
public static void main(String[] args){//写入口。
Scanner in=new Scanner(System.in);//声明扫描仪。
System.out.println("请输入年份:");//提醒用户输入年份
int year=in.nextInt();//声明一个变量year用来接收控制台数据。
System.out.println("请输入月份:");//提醒用户输入月份
int month=in.nextInt();//声明一个变量month用来接收控制台数据。
int sum=0;//声明一个变量存储sum
for(int i=1900;i<year;i++){//循环语句,循环初始值1900年,条件i<year(用户输入的年份),改变循环变量的值
if(i%4==0&&i%100!=0||i%400==0){//选择结构,判断平年闰年
sum+=366;//闰年
}else{
sum+=365;//平年
}
}
for(int i=1;i<month;i++){//循环,初始值为1,1月的意思,循环条件i<month,小于用户输入的month,改变循环变量的值i++。
if(i==2){//如果i=2月
if(year%400==0){
sum+=29;//闰年29天,
}else{
sum+=28;//平年28天
}}else{
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12){//月份分为大月和小月,要判断出来,大月31天
sum+=31;
}else{
sum+=30;//小月30天
}
}
}
int days=0;
/*if(month==2){
if(year%400==0){
sum+=29;
}else{
sum+=28;
}}else{
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
sum+=31;
}else{
sum+=30;
}
sum+=1;*/莫名其妙
int wekday=sum%7;//声明一个变量由天数算出有几个星期。
System.out.println("日\t一\t二\t三\t四\t五\t六");//第一排的标题。制表符用来间隔
for(int i=1;i<=wekday;i++){//循环制表符。有几个星期就循环几次。
System.out.print("\t");
}
for(int i=1;i<=30;i++){//天数
if(sum%7==6){//星期数
System.out.print(i+"\n");
}else{
System.out.print(i+"\t");
}
sum++;
}
     }
  }
}//后面内容看之不懂。


日历注释并非分析思路。写日历程序的思路并非从上到下,而是不断插入,最后优化的结果。拿到日历问题,首先分析问题,分几步?先写什么?再写什么?壁虎老师先写年份,再写月份,次之天数,再次之星期数,最后调试。其中过程,修改添加不断。第一次看时,眼花缭乱,不知所云。现在看来错落有致,水到渠成。


现分步整理壁虎老师思路。


日历1


题目:求1900年1月1日到2015年12月31日相隔多少天?
分析思路,区分平年闰年。平年365天,闰年366天,
public class test{
public static void main(String[]args){
int sum=0;//声明一个变量,用来存储天数。
for(int year=1900;year<=2015;year++){//用一个循环算出都有几个闰年
if(year%4==0&&year%100!=0||year%100==0){
sum+=366;//累加求和,等价于sum=sum+366
}else{
sum+=365;
}
}
System.out.println("1900年至2015年相隔"+sum+"天");
}
}


日历2


求1900年1月1日到2016年5月7日有多少天?
日历1中分析了平年和闰年。现在添加大月和小月。大月31天,小月30天。2月单独算。
public class test{
public static void main(String[]args){
int sum=0;
for(int year=1900;year<=2015;year++){//先算出到2015,再单独算2016年的天数。
if(year%4==0&&year%100!=0||year%100==0){
sum+=366;//累加求和,等价于sum=sum+366
}else{
sum+=365;
}
}
for(int month=1;month<=4;month++){//算出2016年前4月的天数,再加7天
if(month==2){
if(2016%4==0&&2016%100!=0){
sum+=29;
}else{
sum+=28;
}
}else{
if(month==4||month==6||month==9||month==11){
sum+=30;
}else{
sum+=31;
}//嵌套到大循环的外边,没有影响里面sum的累加的。
}

}
}
sum+=7;
System.out.println("1900年1月1日到2016年5月7日共"+sum+"天");
}


日历3


求月份第一天为星期几,方法是求到该天,对7取模,便是星期几。
对日历2代码进行修改
求1900到2012年9月1日有多少天?然后求每月1号的星期几?


public class test{
public static void main(String[]args){
int sum=0;
for(int year=1900;year<=2011;year++){//先算出到2015,再单独算2016年的天数。
if(year%4==0&&year%100!=0||year%100==0){
sum+=366;//累加求和,等价于sum=sum+366
}else{
sum+=365;
}
}
for(int month=1;month<=8;month++){//修改处
if(month==2){
if(2012%4==0&&2012%100!=0){//修改
sum+=29;
}else{
sum+=28;
}
}else{
if(month==4||month==6||month==9||month==11){
sum+=30;
}else{
sum+=31;
}//嵌套到大循环的外边,没有影响里面sum的累加的。
}

}
}
sum+=1;//修改处
System.out.println("2012年9月1日为星期"+sum%7);//修改
}


日历4


求当月有多少天。问2012年9月份的日历。
public class test{
public static void main(String[]args){
int sum=0;
for(int year=1900;year<=2011;year++){
if(year%4==0&&year%100!=0||year%100==0){
sum+=366;//累加求和,等价于sum=sum+366
}else{
sum+=365;
}
}
for(int month=1;month<=8;month++){
if(month==2){
if(2012%4==0&&2012%100!=0){//修改
sum+=29;
}else{
sum+=28;
}
}else{
if(month==4||month==6||month==9||month==11){
sum+=30;
}else{
sum+=31;
}//嵌套到大循环的外边,没有影响里面sum的累加的。
}

}
}
sum+=1;
int weekday=sum%7;//存储星期几
System.out.print("日\t一\t二\t三\t四\t五\t六");//如何让对应的日期在对应的星期数。
for(int i=1;i<=weekday;i++){//%7后,\t循环的次数就与之对应
System.out.print("\t");//用的是print,没有换行。
System.out.ptint("1");//根据题目这次求的是九月1日对应的星期数。
}
}
}
日历5


public class test{
public static void main(String[]args){
int sum=0;
for(int year=1900;year<=2011;year++){
if(year%4==0&&year%100!=0||year%100==0){
sum+=366;//累加求和,等价于sum=sum+366
}else{
sum+=365;
}
}
for(int month=1;month<=8;month++){
if(month==2){
if(2012%4==0&&2012%100!=0){//修改
sum+=29;
}else{
sum+=28;
}
}else{
if(month==4||month==6||month==9||month==11){
sum+=30;
}else{
sum+=31;
}//嵌套到大循环的外边,没有影响里面sum的累加的。
}

}
}
sum+=1;
int weekday=sum%7;//存储星期几
System.out.print("日\t一\t二\t三\t四\t五\t六");//如何让对应的日期在对应的星期数。
for(int i=1;i<=weekday;i++){//%7后,\t循环的次数就与之对应
System.out.print("\t");//用的是print,没有换行。
/*System.out.ptint("1");//根据题目这次求的是九月1日对应的星期数。*/修改处。
}
for(int i=1;i<=30;i++){//求每天对应的天数。
if(sum%7==6){//皆为星期六的日期
System.out.print(i+"\n");
}else{
System.out.print(i+"\t");
}
sum++;//每算出一个,天数加1,这样就横着走,而非竖着走

}
}
}


日历6【综合】


import java.util.Scanner;//添加处
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);//添加处
System.out.println("请输入年份:");//添加
int year=in.nextInt();//添加
System.out.println("请输入月份:");//添加
int month=in.nextInt();//添加
int sum=0;
for(int i=1900;i<year;year++){//修改处
if(i%4==0&&i%100!=0||i%100==0){
sum+=366;//累加求和,等价于sum=sum+366
}else{
sum+=365;
}
}
for(int i=1;i<month;i++){//修改
if(i==2){
if(year%4==0&&year%100!=0||year%400==0){//修改
sum+=29;
}else{
sum+=28;
}
}else{
if(i==4|i==6||i==9||i==11){
sum+=30;
}else{
sum+=31;
}//嵌套到大循环的外边,没有影响里面sum的累加的。
}

}
}
sum+=1;
int weekday=sum%7;//存储星期几
System.out.print("日\t一\t二\t三\t四\t五\t六");//如何让对应的日期在对应的星期数。
for(int i=1;i<=weekday;i++){//%7后,\t循环的次数就与之对应
System.out.print("\t");//用的是print,没有换行。
}
for(int i=1;i<=30;i++){//求每天对应的天数。
if(sum%7==6){//皆为星期六的日期
System.out.print(i+"\n");
}else{
System.out.print(i+"\t");
}
sum++;//每算出一个,天数加1,这样就横着走,而非竖着走

}
}
}//这个日历,因为没有判断月份的天数。输出的结果是1月有30天,事实上,1月有31天。问如何判断每月的天数?这个天数放在哪个位子?
前面已经讲了每月的天数,if(i==4|i==6||i==9||i==11){
sum+=30;
}else{
sum+=31;
}这里是用来加总天数的,可以不加总天数。
int days;
if(i==2){
if(year%4==0&&year%100!=0||year%400==0){
days=29;
}else{
days=28;
}
}else{
if(i==4|i==6||i==9||i==11){
days=30;
}else{
days=31;
}
问题是,这段代码插入到哪里呢?这里面循环很多,我要判断的就是它和各循环的关系。
应该是这个循环:【for(int i=1;i<=30;i++){//求每天对应的天数。
if(sum%7==6){//皆为星期六的日期
System.out.print(i+"\n");
}else{
System.out.print(i+"\t");}】
修改成:
int days;
if(i==2){
if(year%4==0&&year%100!=0||year%400==0){
days=29;
}else{
days=28;
}
}else{
if(i==4|i==6||i==9||i==11){
days=30;
}else{
days=31;
}
}
for(int i=1;i<=days;i++){//求每天对应的天数。修改了days。
if(sum%7==6){//皆为星期六的日期
System.out.print(i+"\n");
}else{
System.out.print(i+"\t");}
}


解决问题,纵然出错,也觉身轻如燕。


敏友讲过一句话,复制是最便捷的学习方式。想到大一体育课,老师教二十四式太极。学的认真,天冷心烦之时,时常练练。老师一个招式,学生便一个招式。这就是复制,复制的好,效果就好。问题的关键是我要复制谁的知识呢?


数年前,觉自己骨格清奇非俗流。哈哈,却原来腹内草莽人轻浮。




《初学Java》系列四


第五章 数组 常用算法


Java虚拟机。(JVM)我听的晕晕乎乎。应该是为了后面的数组铺垫。
栈区和堆区的概念。
简单的说,栈区就是为了存放局部变量。可能错,但先这样理解。
堆区,主要是对象,new对象放在堆区。不定时检测无用对象,报错处理。
现在我总结栈区和堆区的不同用处。
基础数据类型的声明和调用在栈区,变量也在栈区。引用类型、创建对象在堆区。栈区需要堆区的数据,但是堆区不需要栈区的数据。好,就这样理解。


数组
1、声明 2、使用。数组是相同数据放在一类。数组是从0开始的。
我在想一个问题,如果是让我讲,我会怎样讲数组?哈哈,难题。
书架名→数组名称(标识符)
书本→数据
书本编号→下标
1、声明数组。int[]a;(a是数组的名称,声明之后在栈区有了位置,但是没有空间)
2、分配空间。a=new int[5](意思是分配5个相应的空间。下标是01234,分配了空间,没有赋值,初始值为0)
3、赋值。a[0]=8;(0下标空间的数据为8)
4、处理数据。b=a[0]*5(这样就使用了。)


public class test{
public static void main(String[]args){
int[] a;//声明数组,命名数组名称
a=new int[3];//分配空间。这样看着别扭。int a[]=new int[3];这样是不是简洁些。
a[0]=3;//赋值
a[1]=2;
a[2]=1;
System.out.println(a[0]);//输出0下标存储的数据,结果是3
}
}


声明变量和声明数组不同,后者是new int[].我并不知道什么意思。但是和Java创建对象有关。


public class test{
public static void main(String[]args){
int[] a=new int[5];//声明数组,命名为a,分配了5个空间。
a[0]=100;//赋值。
System.out.println(a[0]);//输出的结果是100
}
}


另外,int[] a={1,2,3};//声明→分配空间→赋值。局限下,代码简洁些。注意,引用数据不能超出分配的空间。a[3]是不存在的。会数组越界,报错。总之是找不到



数据类型→数组类型
int[]这是数组类型的符号。new int[]就是创建对象,放在了堆区。莫非栈区是虚拟出来的?这部分内容,可以扯上《数据结构》《操作系统》,可惜,学识浅薄,无人请教。


public class test{
public static void main(String[]args){
int[] a=new int[3];//int[]a在栈区,new int[3]在堆区。
System.out.println(a[0]);//这句代码是通过a[],去的堆区访问了a[0]这个数据,因并未赋值,默认数值为0,得出的结果是0


}
}


String[] a=new String[]只声明没有赋值,为null


键盘赋值
这个就是用户赋值了。这个是后来是学生成绩管理程序的基础啊。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
int[] s=new int[3];
int sum=0;//用来存储总成绩。
for(int i=0;i<3;i++){//i是从0开始的。输入成绩循环
System.out.println("请输入成绩:");
s[i]=in.nextInt();//接收数据。i是从0下标开始。
sum+=s[i];//累加求和。等价于sum=sum+s[i]
}
System.out.println("学生总成绩为:"+sum);
}
}//代码我没有运行,细节会错。


length属性的用法


import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
int[] s=new int[3];//声明一个数组。分配的空间3个,长度为3
int sum=0;//用来存储总成绩。
for(int i=0;i<s.length;i++){//i是从0开始的。输入成绩循环
System.out.println("请输入成绩:");
s[i]=in.nextInt();//接收数据。i是从0下标开始。
sum+=s[i];//累加求和。等价于sum=sum+s[i]
}
System.out.println("学生总成绩为:"+sum);
}
}//s.length就是所声明的数组的长度。


题目:让用户自己定义数组长度。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请定义学生的人数:");
int num=in.nextInt();//接收数据。接收用户定义的人数
int[] a=new int[num];//把用户定义的人数给了数组,程序里的含义是定义了数组长度。声明一个数组a,用来存储用户输入的数据。
int sum=0;
for(int i=0;i<a.length;i++){
System.out.println("请输入第"+i+"个学生成绩");
a[i]=in.nextInt();
sum+=a[i];
}
System.out.println(a.length+"个学生的总成绩为:"+sum);
}
}


题目:求数组中的最大值。
问,输入五个学生的成绩,求分数最高的。原理是依次比较。
import java.util.*;
public class test{
public static void main(String[]args){
//声明一个数组
int[] a=new int[5];
for(int i=0;i<a.length;i++){//循环接收用户输入的数据
System.out.println("请输入第"+(i+1)+"个学生的成绩");
a[i]=in.nextInt();
}
//循环比较输入成绩的大小。
//声明一个变量存储比较的结果
int max=a[0];//从下标0中的数据开始
for(int i=0;i<a.length;i++){
//用条件结构进行比较,条件也是选择。
if(max<a[i]){
max=a[i];
}
}
System.out.println("最高分为:"+max);
}
}


数组的排序
打擂台的思路就是if处理。
题目:循环录入5个学生的成绩,升序排列输出结果。
出现一个Arrays类。是个新东西。还没有讲类和方法呢!
import java.util.Scanner;
import java.util.Arrays;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
int[] a=new int[5];
for(int i=0;i<a.length;i++){
System.out.println("请输入第"+(i+1)+"个学生的成绩");
a[i]=in.nextInt();
}
Arranys.sort(a);//升序排列。对数组a里面的值进行升序排列。这单词我是记不住的。
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}

}
}


题目:逆序输出英文字母。
import java.util.*;
public class test{
public static void main(String[]args){
//声明扫描仪,用来接收控制台的数据。
Scanner in=new Scanner(System.in);
//声明一个数组,用来存储接收的数据。是字符串哦
  声明的时候,分配空间。
String[] a=new String[7];
//循环接收数据。其实,可以让用户自己定义数组长度。
for(int i=0;i<a.length;i++){
System.out.println("请输入第"+(i+1)+"个字母");
a[i]=in.next();
}
//注意放在循环中的位置。
//对数组中的数据进行排序。
Arrays.sort(a);
//循环输出排序结果,但是是逆序输出。如何用for循环实现?
for(int i=a.length;i>=0;i--){
System.out.println(a[i]);
}
}
}


数组算法


1、数组复制
public class test{
public static void main(String[]args){
//声明两个数组,一个赋值,一个不赋值
int[] a={1,2,3};
int[] b=new int[a.length];
//用for循环赋值
for(int i=0;i<a.length;i++){
b[i]=a[i];
}
System.out.println(b[i]);
}
}


2、查找算法或搜索算法
原理就是找一遍数组中的数据。
import java.util.Scanner;
public class test{
public static void main(String[]args){
//声明Scanner,扫描仪嘛
Scanner in=new Scanner(System.in);
//提醒用户输入
System.out.println("请输入要找的姓名:");
//声明一个变量用来接收
String name=in.next();
//声明一个数组用来存储已有的数据
String[] a={赵,钱,孙,李};
//题目要求,不管重名,找到一个就结束。声明一个变量用来判断
boolean f=false;
//用循环结构遍历数组中的数据。
for(int i=0;i<a.length;i++){
//用if判断是否找到相同的姓名
if(name.equals(a[i])){
//不是,继续遍历。是,结束循环。如何结束
f=true;
break;
}
}
//输出结果。
if(f=true){
System.out.println("找到了");
}else{
System.out.println("抱歉!查无此人。");
}
}
}


3.插入算法
为什么不叫成替换算法?这个题目,不仅是插入,还是排序啊。因为长度不是用户定义的。
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
//声明一个数组存储数据
int[] a={1,2,3};
//提醒用户输入数据。
System.out.println("请输入要插入的数值");
//声明一个变量用来接收数据。
int b=in.nextInt();
//这个不是插入,这个是替换掉最小的数值啊!第一次看没有看出其中问题,现在看后面评论,觉得颇有道理。心中好痒啊。
a[arr.length-1]=b;//这个是从最大的下标开始赋值。但是并不是赋值给最大的下标,而是遍历谁最小,替换掉最小的数值。
for(int i=a.length-1;i>0;i--){//i>0,为的是防止下面的数组越界。
   if(arr[i]<arr[i-1]){
//这个是交换两个数值的方法。
int c=a[i];
a[i]=a[i-1];
a[i-1]=c;
  }else{
break;
}
}
//接下来循环输出
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
}


冒泡排序


public class test{
public static void main(String[]args){
//声明一个数组
int[] a={1,2,3,4,5,6};
for(int i=0;i<a.length-1;i++){
//a.length-1是因为下标。循环的目的是为了排出最大数
//前一个下标大于后一个下标
if(a[i]>a[i+1]){
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
}
如果不仅仅是找出最大值,而是要把这些数据排序呢?1、Arrays。2、冒泡排序。但是上述例子内容不够,有6个数值,只找到最大,其他数值要用循环嵌套处理。如下:
public class test{
public static void main(String[]args){
//声明一个数组
int[] a={1,2,3,4,5,6};
for(int i=0;i<a.length;i++){
for(int i=0;i<a.length-1;i++){
//a.length-1是因为下标。循环的目的是为了排出最大数
//前一个下标大于后一个下标
if(a[i]>a[i+1]){
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
//循环输出结果
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
}
}//代码没有运行检验。想到一个问题,不如让用户自己定义数组长度。还有从大到小怎么排序?改变if中的代码便是了。


5.选择排序
  ----------------
  | | | | | | | |
  ----------------
选择排序的代码和冒泡排序代码只有微小差别,但是背后含义却大不相同。从减少比较的次数理解。冒泡排序是第一次所有数据比较,找出老大。第二次还是所有数据比较,然后找出老二。第三次还是所有数据比较,找出老三。每次都要所有数据参与。但是选择排序,首次,选出老大。老大休息。第二次比较,数值总数-1.以此类推,每次比较都要-1.对比次数减少。效果一样。


for(int i=0;i<a.length-1;i++){
for(int j=i+1;j<a.length-1;j++){
if(a[i]>a[j]){
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}//同样效果,但是效率不同。


public class test{
public static void main(String[]args){
//声明一个数组
int[] a={1,2,3,4,5};
//a.length=5,但是下标从0开始,还有就是,最后一个数不用比较,用<,而非<=
for(int i=0;i<a.length-1;i==){
for(int j=i+1;j<a.length;j++){
if(a[i]>a[j]){
//交换数值
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
System.out.println(a[i]);
}
}


多维数组
int a[][]={{},{},{}}
二维数组存储的是数组的下标,数组的数组。int a[][]={{1,3},{4,5,6},{78,9}}
a[][],一个是表示数组中有几个数组,一个是表示小数组中可以放几个数据数。就是这是分配一次空间,又分配了一个空间。分配两次空间
【参照应老师文章:http://mp.weixin.qq.com/s?__biz=MzI4ODYwNTM3Ng==&mid=2247483866&idx=1&sn=54bda8811c5e50263fc6ebe770c8d3a7&chksm=ec3a9475db4d1d63f0cb23a02d062547b49dfb04233d63abd8581b858f86b8bbd817bfd55579&mpshare=1&scene=23&srcid=02249P4Yal1HRWbiPoLGBu3T#rd
《从几何意义理解四则运算优先级》】
a[3][4]表示可以存三个数组,每个数组可以有四个数据。
还是上代码吧
public class test{
public static void main(String[]args){
//声明并赋值
int[][] a={{1,2}{4,5}{7,8,9}};
}
System.out.println(a[1][1]);//数组中的下标是从0开始的,结果是{4,5}中的5.
}


二维数组的声明方式
int[][] a=new int[3][];
a[0]=new int[3];
a[1]=new int[2];
a[2]=new int[1];
意思就是说,二维数组中有三个数组,第一数组有三个空间,第二个数组有2个空间,第三个数组有1个空间。


今天可以结束第五章。只剩下一个实例了。


简单的学生成绩程序
这是最后的结果:
import java.util.*;
public class A4{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.println("请输入学生人数:");
int renshu=in.nextInt();//存储学生人数
System.out.println("请输入课程数目:");
int courseNum=in.nextInt();//存储课程数目
String[] name=new String[renshu];//声明一个变量String用来存储学生姓名
String[] course=new String[courseNum];//声明一个变量String用来存储课程名称
int[][] number=new int[renshu][courseNum];
int[] sum=new int[renshu];//声明一个变量int数组用来存储sum
int[] avg=new int[renshu];
String[] str=new String[renshu];
/*用来循环课程名称*/
for(int i=0;i<course.length;i++){
System.out.println("请定义第"+(i+1)+"门课程名字:");
course[i]=in.next();
}
/*用来录入学生课程成绩*/
for(int i=0;i<renshu;i++)
{
int S=0;
System.out.println("请输入第"+(i+1)+"学生姓名:");
name[i]=in.next();//用来存储学生姓名
String str11="";
for(int j=0;j<courseNum;j++){
System.out.println("请输入学生"+name[i]+course[j]+"成绩");
number[i][j]=in.nextInt();//用来存储特定学生的特定成绩
S+=number[i][j];//加总输入的学生成绩,+=是叠加。
str11+=number[i][j]+"\t";
}
sum[i]=S;//这是赋值成为总分
avg[i]=S/courseNum;
str[i]=name[i]+"\t"+str11+sum[i]+"\t"+avg[i];//
}
for(int i=0;i<str.length-1;i++){
for(int j=0;j<sum.length-1;j++){
if(sum[j]<sum[j+1]){
int t1=sum[j]; String t2=str[j];
sum[i]=sum[j+1]; str[j]=str[j+1];
sum[j+1]=t1;  str[j+1]=t2;
}
}
}
/*效果输出*/
System.out.print("学生");
for(int i=0;i<course.length;i++){
System.out.print("\t"+course[i]);//输出课程名称
}
System.out.print("\t总分\t平均分\t排行榜");
System.out.println();
for(int i=0;i<renshu;i++){
System.out.println(str[i]+"\t第"+(i+1)+"名");
}
}
}


我们来分析思路,一步一步分析。我不想一步一步写代码了。这次主要看思路
1.让用户定义学生人数。renshu=in.nextInt()
2.让用户输入科目数目。courseNum=in.nextInt()
3.声明一个数组用来保存学生姓名。String[] name
数组的长度是学生renshu
4.声明一个数组用来存储科目名称 String[] course
长度是course
5.循环让用户输入科目名称。循环条件是i<courseNum
科目名称存到数组course[]
6.循环让用户输入学生姓名。循环条件是j<renshu
学生姓名存储到数组name[]
7.输入每个学生对应每科成绩,用嵌套循环实现。
大循环是6,小循环输入成绩,判断条件是i<courseNum
8.声明数组存储成绩
学生 经济学 操作系统   数据库   平均分   排行榜
似花非花人 90   45     45     60    第一名


壁虎老师 0    0         0      0     第二名


{90,45,45,60}这是一个数组,说明是用二维数组接收成绩。
定义二维数组,number=new int[renshu][course]比如90的位置是number[0][0]因为数组的坐标是从0开始的。
number={{90,45,45},{0,0,0},{},......}
平均分和排行榜不是一个数组。


9.打印标题
学生 经济学 操作系统   数据库   平均分   排行榜
学生、课程名与平均分和排行榜不在一个程序体中。
它们不在任何循环中,而是在入口处。
①在学生标题下出现学生姓名。然后姓名和成绩在同一行,加入8数组。
②计算平均分和排行榜。然后平均分下面出现分数和排行榜。并非8的数组。


我还是不会写。如同我背过一篇英文,但是我写不出来。看过别人的经济学分析,我自己却解释不出。
1、我脑子里没有系统。2、我想不到下一步要分析的内容。3、我想不到有什么知识可以使用。


壁虎老师写学生成绩管理程序。给了一个成品的结果,然后分析这个结果是怎么做出来的。令我想到第一章讲过的用程序解决问题的思路。


课本上是这样讲的,软件开发过程:问题定义→设计解决方案→编写程序→测试、运行。


什么是问题定义?课本上说,这个阶段要弄清楚以下几个问题;(1)程序的目标是什么?需要程序解决什么问题?应该实现的功能是什么?(2)可能需要输入哪些数据?(3)数据具体的处理过程和要求是什么(4)程序可能的输出数据是什么?表现形式是什么?


壁虎老师示范清楚了。


《初学Java》系列五


第六章《一》


与之前内容不同,主讲类和对象使用。内容多,分开写。


内存分析


简单总结一番,程序→main方法→执行过程。
也是操作系统知识。主讲执行过程。
我们来看程序:
public class test{
public static void main(String[]args){
//j是一个局部变量,作用域是整个主程序
//判断作用域,看大括号。
int j=34;
while(true){
int i=9;
System.out.println(i);
}
//下面代码不能够执行,i是局部变量,作用域在里面。
System.out.println(i);
}
}


类和对象


面向过程?面向对象?
开车去北京,1、开车门。2、做到车上。3、选择路线。4、......(面向过程)
   1、司机,去北京。(面向对象)
类和对象的定义,人类→似花非花人→男→单身.....


自己是女娲,抓一块泥巴,捏成男人就是男人,捏成女人就是女人,捏成小孩就是小孩。
对象自己造出来。类是创建的,对象也是创建的。
先创建类,后创建对象。类名,首字母大写。


文件1→Person.java
public class Person{
//人要有属性,要有行为。
//先定义属性。
String name;//通常不在类里面赋值,而是在创建的对象中赋值
String gender;
int age;
//再定义行为。
public void eat(){//无参无返回,void是无返回。eat是参数,()放参数。
System.out.println("吃饭");
}

}


文件2→test.java
public class test{
public static void main(String[]args){
//Person这个类是文件1中创建的Person类。两个文件放在同一个目录下所以直接使用,无improt
//创建一个对象,必须用new
//创建了一个对象,名MyPerson
Person MyPerson=new Person;
//使用类的属性。对象名+成员变量(属性名)
//赋值
MyPerson.name="似花非花人";
//访问对象的属性。
System.out.println(MyPerson.name);
//使用对象的方法
//访问对象的方法
MyPerson.eat();//会输出吃饭。因为在创建类的时候,赋值就是“吃饭”。
}
}


类有两种可能,一个是Java自带。一个是自己创建。自带不必多讲,import java.util.Scanner;
用代码分析:
public class test{
public static void main(String[]args){
Scanner in=new Scanner(Systerm.in);
}//Scanner类是引用类型。放在util包中,是Java自带的类。Java不可能写出所有所需的类。操作者在不同局限下,需要不同的类,自己创建有更大便利。类似于理论的一般化。
创建一个类,如果是用记事本创建,文件名为类名,比如Person.java ,一个类,分为两部分,成员变量(属性)和成员方法(行为、操作),创建一个类,就是定义一个类的两部分。
public class Person{
String name;
String sex;
int age;
float height;


public void eat(){
System.out.println("吃");
}
}


创建一个类成功后,使用创建的类。
public class test{
public static void main(String[]args){
//通过创建对象使用创建的类。
Person MyPerson=new Person;
//赋值
MyPerson.name="壁虎老师";
MyPerson.eat();
System.out.print(MyPerson.name);//结果是:壁虎老师吃
}
}
接着上面内容
public class test{
public static void main(String[]args){
Person One=new Person;
System.out.println(One.age);

Person Two=new Person();
System.out.println(Two.age);
}
}


分析上述代码:new Person是创建的对象,属性放在堆区。而变量名在栈区。通过变量名one(栈区)访问堆区的属性。
总结一下,1.必须使用new关键字创建一个对象。2。使用对象属性。3。使用对象方法 4.同一个类的每个对象有不同的成员变量的存储空间 5.同一个类的每个对象共享该类的方法。


有参无返回
public class Person{
String name;
int age;


//无参无返回 方法
public void eat(){
System.out.println("吃饭");
}
//有参无返回
public void sleep(String A){
System.out.println("我在"+A+"睡觉");//区别于我在睡觉。有了参数。
}
}
有参无返回方法的使用
public class test{
String One=new Person;
//下面是用会报错,因为前面Person类中,sleep是有参数,下面却未给参数。
One.sleep();
//下面是正确使用。
One.sleep("沙发");//结果是我在沙发上睡觉。区别于我在睡觉
}


有参有返回
public class Person{
String name;
int age;


//无参无返回
public void eat(){
System.out.println("吃饭");
}
//有参无返回
public void sleep(String A){
System.out.println("我在"+A+"睡觉");

//有参有返回
//1.int解释。2.getAge解释。这个是取值操作,get具有默认的效果。众所周知,约定俗成的规范。出现get就是取值之意
//3.int a解释 4.return a解释
public int getAge(int a ){
return a;//下文详解return用法
}
}//a的数值是没有的,int a 是参数的意思。是操作者定义的参数。
Person a=new Person;
a.getAge(18);//int类型,只能是整型数值。此时的含义就是a.getAge(18)=18


Person a=new Person;
int age=a.getAge(18);//声明一个变量并赋值。和以前不同的是,理解了类的方法。还是有参有返回的方法。


成员变量
public class test{
//声明成员变量。不赋值也能使用,默认值各有不同,引用类型为null
//不赋值的成员变量,默认值:byte为0,short=0,int=0,long=0L,
//char='\u0000',float=0.0F,doubule=0.0D,boolean=false,所有引用类型为null
static int a;
public static void main(String[]args){
//局部变量声明
int age;
System.out.println(age);//报错,因为没有赋值。
}
}


return和多参
return是关键字,return的使用。使用类的时候,如果是写在记事本,1、类和主程序写在两个记事本中。2、类和主程序写在一个记事本文件中。


类和主程序写在一个记事本文件里。
1、文件名,只能出现一个public
//先创建一个Dog类
class Dog{//先写一个属性name
String name;
//再写一个方法,public是写方法的语句。
//public void→是无返回类型的方法。去掉void就是又返回类型的方法
//返回类型是String(字符串),方法名是print(随意取)
//print()这个是无参数→print(String)定义了String类型的参数
//a是形参的名称。在类的方法中定义的参数的名称都是形参。有名字。
//一个方法中可有多个形参。
public String print(String a){
System.out.println(a);
}
}
//写主程序
public class test{//一个程序,public只能一个,文件名以此为准。这个记事本名字是test.java 。class是一个类。
//
public static void main(String[]args){
//写好入口,创建一个对象。生成一只狗
//Dog()
Dog d=new Dog();
//调用Dog类中的print方法,这个方法有参数,我们必须为他传递一个参数。print的参数是a。类型是String,就是String a
d.print("二哈");//二哈传到哪里了?传给形参a了。现在a就代表了二哈。a是个形参,二哈是个实参。传过去之后呢?在Dog类中执行了这样一段代码,public String print(String a){
System.out.println(a);
}→输出a的值,即二哈//事实上是不会执行的,因为没有返回语句。会报错。不会被执行。return是返回有指定类型的值。所以应该使用return语句。
/* public String print(String a){
System.out.println(a);
return a;//这时候输出的结果才是二哈
} */
}
}


现在整理代码。刚才的注释眼花缭乱
class Dog{
String name;
public String print(Sting a){
System.out.println(a);
return a;
}
}
public class test{
public static void main(String[]args){
Dog d=new Dog();
String name=d.print("哮天犬");
System.out.println(name);//输入的name是就近原则,不是Dog类中的类。
}
}//会出现两个哮天犬,一个是Dog中return,一个是主程序中的。


return的第二个用法,结束执行
class Dog{
String name;
public String print(Sting a){
System.out.println(a);
return a;
}
public void str(int b){
if(b==0){
System.out.println("你好");
}else if(b==1){
return;
}
System.out.println("我很好");
}
}
public class test{
public static void main(String[]args){
Dog d=new Dog();
d.str(0);//0传递给了b形参。然后输出你好 我很好。
d.str(1);//在Dog中执行了else if 中的return.结束执行。什么也不会输出。
}
}
多参
class Dog{
String name;
public String print(Sting a,int x,char y){
System.out.println(a);
System.out.println(x);
System.out.println(y);
return a,x,y;
}
}
public class test{
public static void main(String[]args){
Dog d=new Dog();
d.print("哮天犬",10000,'雄');
}
}//最后的结果会把Dog中的内容输出,而非主程序中的内容。


toString
默认输出的一个类。
class Cat{


}
/*public class test{
public static void main(String[]args){
String name=new String("你好");
System.out.println(name);//自动调用toString方法。
System.out.println(name.toString());
}
}*/
没有定义就调用的情况
/*public class test{
public static void main(String[]args){
Cat one=new Cat();
System.out.println(one.toString());//输出的是哈希码值
}
}*/
定义toString再调用
class Cat{
String name;
int age;
public String toString(){
return"姓名"+name+"年龄"+age;
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat();
one.name="小猫咪";
one.age=123456789;
System.out.println(one.toString());
System.out.println(one);
}
}//运行的时候注意符号。必须是英文状态下的符号


this的使用
首先是创建类,然后是主程序中使用类创建对象
以下是源代码,
class Cat{
String name;
int age;
String color;
public void set(String name,int age,String color){
this.name=name;
this.age=age;
this.color=color;
}
public String toString(){
return "姓名"+name+"\t年龄"+age+"\t颜色"+color;
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat();
Cat two=new Cat();
one.set("第一只猫",5,"黑色");
two.set("第二只猫",6,"白色");
System.out.println(one);
System.out.ptintln(two);
}
}
好,来分析源代码:(不厌其烦,重复分析。)
//创建一个Cat类
class Cat{//先写属性,数据类型和名称。
String name;
int age;
String color;
//再写方法。第一个方法,有参无返回。因为有void,所以是无返回。
//方法名是set,参数有name,age,color
//this.name
public void set(String name,int age,String color){
this.name=name;
this.age=age;
this.color=color;
}
//第二个方法,无参有返回,返回类型是String(字符串),方法名是toString
//关键字是return 返回内容是"姓名"+name+"\t年龄"+age+"\t颜色"+color  (return是返回有指定内容的值。)
public String toString(){
return "姓名"+name+"\t年龄"+age+"\t颜色"+color;
}
}
//主程序。
public class test{
public static void main(String[]args){
//在Cat类中创建几个对象。
Cat one=new Cat();
Cat two=new Cat();
//赋值one.set背后的意思是调用了Cat类中的名为set方法
//
one.set("第一只猫",5,"黑色");
two.set("第二只猫",6,"白色");
//输出
System.out.println(one);
System.out.ptintln(two);
}
}
很好。但是并没有扯到this的使用。下面的代码才会扯到this
class Cat{
String name;
int age;
String color;
public void set(String name,int age,String color){
this.name=name;
this.age=age;
this.color=color;
}
public String toString(){
return "姓名"+name+"\t年龄"+age+"\t颜色"+color;
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat();
Cat two=new Cat();
one.set("第一只猫",5,"黑色");
two.set("第二只猫",6,"白色");
System.out.println(one);
System.out.ptintln(two);
}
}//堆中有了对象。这句话怎么理解?Cat one=new Cat();实在堆中分配了一个空间。在Cat类中创建几个对象。因为类在堆中,所以创建的对象也在堆中。对象的成员变量(属性)和成员方法分别是什么?
//栈中就有了对象的引用。这句话怎么理解?栈中没有对象。先引用对象,再使用对象。1、怎么引用?Cat one=new Cat();这个就是了。名字叫one
//对象名在栈中,对象在堆中。将军的虎符在将军手中,但是士兵在大营。
//one.set调用one对象的方法。1、怎么调用?方法中有什么内容?
这个是方法,里面有name age color,然后给它传了内容(猫,5,黑色)。问题,1。谁给谁传了内容?2、传的内容存储在哪里?内容在栈中,但是内容传到了堆区。实参的内容传给形参。内容在栈中。
//三个变量都是有值了。值是传过去的。
//如果能设置断点,我就验证执行过程。
//逻辑上的执行过程:
one.set()→public void set


("第一只猫",5,"黑色");→(String name,int age,String color)→  ↓


this.name=name;//把name赋值给了this.name
this.age=age;//把aga赋值给了this.aga
this.color=color;//把color赋值给了this.color
(1、this代表使用该方法的引用,什么意思呢?现在one在使用这个堆区的对象。this对应one。它的意思就是one的意思。如果是two,this就对应这two,这是实参传入的对象就是two的。
2、this.name 指调用了成员属性String name,然后把name赋值给它,这个name是实参传过来的数据)



System.out.println(one);→public String toString(){
return "姓名"+name+"\t年龄"+age+"\t颜色"+color;
}(输出的数据是赋值后的结果,即 →第一只猫,5,黑色)


(this的作用,避免了重名。没有name的结果就是,name=name)

内存示意图:
【栈区“one,two  name,age,color”






  堆区“one(name,age,color) two(name,age,color)”】


验证如下:
class Cat{
String name;
int age;
String color;
public void set(String name,int age,String color){
this.name=name;
this.age=age;
this.color=color;
}
public String toString(){
return "姓名"+name+"\t年龄"+age+"\t颜色"+color;
}
public Cat aaa(){
return this;
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat();
Cat two=new Cat();
one.set("第一只猫",5,"黑色");
two.set("第二只猫",6,"白色");

Cat three=new Cat();
three=one.aaa();
System.out.println(three);
System.out.println(one);
}
}
输出的结果是:
第一只猫,5,黑色
第一只猫,5,黑色


为什么这样?执行过程如下:
one.aaa()

public Cat aaa()

return this;

this.name=name;//这些都是one的内容。
this.age=age;
this.color=color;


总结,这次的收获并非this的使用。而是堆区和栈区的执行过程。


封装
class Student{
String name;
int age;
char gender;
}
public class test{
pubulic static void main(String[]args){
Student one=new Student();
one.gender='男';
System.out.println(one.gender);
}
}
分析代码,不厌其烦,复制思路
//创建Student类。
class Student{
//属性,name,age,gender(性别)
String name;
int age;
char gender;
}
//主程序
public class test{//框架
pubulic static void main(String[]args){//入口
//在Student类中创建一个对象。
Student one=new Student();
//调用成员属性,赋值
one.gender='男';
//输出。
System.out.println(one.gender);
}
}
通过例子理解封装,对代码再分析
class Student{
String name;
int age;
private char gender;
public void setGender(char gender){
if(gender=='男'||gender=='女'){
this.gender=gender;
}else{
System.out.println("请输入正确的性别!");
}
}
public char getGender(){
return this.gender;
}
}
public class test{
public static void main(String[]args){
Student one=new Student();
one.setGender('男');
System.out.println(one.getGender());
}
}
---------------------------------------
class Student{
String name;
int age;
//private 私有的。访问权限设置,只能在Student类中访问。
//在主程序中要如果不是专门设置,不能访问。如何才能访问?
private char gender;
//在本类里面提供一个公有方法。setGender是方法名。
//set是设置,约定俗成,意思是给成员属性做设置的。字母大写是规范
//通过参数设置权限。char gender
public void setGender(char gender){
//约束传递过来的内容。这里只要求男女。
//符合男女,接收传递的内容。
if(gender=='男'||gender=='女'){
//this用于区分谁是谁。
this.gender=gender;
}else{//拒绝传递内容。
System.out.println("请输入正确的性别!");
}
}
//设置了访问权限,不能直接输出,要再写一个方法,目的是用于输出
//返回的类型是char,要返回gender,自然是char
//get是取出的意思。意思是取出当前this.gender
public char getGender(){
return this.gender;
}
}
public class test{
public static void main(String[]args){
Student one=new Student();
//修改访问权限。Student类中给了通道
one.setGender('男');
System.out.println(one.getGender());
}
}//封装,就是约束一些内容。哪些放开,哪些约束,根据情况而定。
做法,1、修改属性的访问权限。private 2.为该属性创建两个方法,取值方法和赋值方法。如getGender setGender


方法的重载


展示分析思路,事无巨细,不厌其烦。


class Student{
public void max(int a,int b){
System.out.println(a>b?a:b);
}
}
public class test{
public static void main(String[]args){
Student one=new Student();
one.max(7,4);
}
}
---------------------------------------------------------
//创建一个Student类
class Student{//类的方法,名max。没有给属性。不返回有参数。参数类型int
public void max(int a,int b){

//三元运算符。a大于b吗?true,输出a;false,输出b
System.out.println(a>b?a:b);
}
}
//主程序
public class test{//框架
public static void main(String[]args){//入口
//创建一个对象one
Student one=new Student();
//调用Student类中成员方法max,传了两个数。
one.max(7,4);
}
}
-----------------------------------------------------------
分析方法重载,对比不同数值,类中的方法名max,maxDouble,maxThree
class Student{
public void max(int a,int b){
System.out.println(a>b?a:b);
}
public void maxDouble(double a,double b){
System.out.println(a>b?a:b);
}
public void maxThree(int a,int b,int c){
int max=a>b?a:b;
System.out.println(a>b?a:b);
}
}
public class test{
public static void main(String[]args){
Student one=new Student();
one.max(7,4);
}
}
-------------------------------------------------------------------
三个方法,只有一个名字max
class Student{
public void max(int a,int b){
System.out.println(a>b?a:b);
}
public void max(double a,double b){
System.out.println(a>b?a:b);
}
public void max(int a,int b,int c){
int max=a>b?a:b;
System.out.println(a>b?a:b);
}
}
public class test{
public static void main(String[]args){
Student one=new Student();
one.max(7,4);//主程序中会自动选择合适的方法。尽管名字一样。此处调用第一个方法。
one.max(4,5,6);//调用第三个方法。
}
}


构造方法(构造函数)


class Cat{
String name;
int age;
Cat(){

}
Cat(String name,int age){
this.name=name;
this.age=age;
System.out.println("姓名"+this.name+"年龄"+this.age);
}
void get(){
System.out.println(this.name);
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat("似花非花人",100);
one.get();
}
}
------------------------------------------------
//创建类
//1、有无构造方法效果对比。2、构造方法和普通方法效果对比。
class Cat{
String name;
int age;
//第一个构造方法,里面为null 构造方法与类同名。Cat
Cat(){

}
//第二个构造方法。
Cat(String name,int age){
this.name=name;
this.age=age;
System.out.println("姓名"+this.name+"年龄"+this.age);
}
//普通方法。用来对比。因为有void
void get(){
System.out.println(this.name);
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat("似花非花人",100);//构造方法用来初始化
one.get();
Cat two=new Cat("hah",13);
two.get();
}
}//构造方法是用来初始化的。
最简单的构造方法用之创建对象Cat one=new Cat()




第六章(二)


题目:学生管理程序


规则 1、方法或属性首字母小写 2、类名首字母必须大写。3、驼峰标志。
通过一个程序例子讲解类,对象、封装、关键字。从写项目理解什么是面向对象。


在记事本中表达不出程序的效果,大概如下:
请选择你要执行的功能:
10:添加一个学生
11:查找一个学生
12:根据学生编号更新学生基本信息
13:根据学生编号删除学生
14:根据编号输入学生各门成绩
15:根据某门成绩进行排序
16:根据总成绩排序
99:退出系统


输出结果:
编号 姓名 年龄 Java html 经济学 总分 平均分
..
..
......
-------------------------------------------------------------------
现在分析写作思路:
首先创建Student类。定义学生属性


class Student {
//封装属性
private int on;
private String name;
private int age;
private int java;
private int html;
private int economic;
private int sum;
private int avg;

//约束方法 取值和赋值
public void setOn(int on){
//赋值
this.on=on;
}
public int getOn(){
//取值
return this.on;
}
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 int getJava() {
return java;
}
public void setJava(int java) {
this.java = java;
}
public int getHtml() {
return html;
}
public void setHtml(int html) {
this.html = html;
}
public int getEconomic() {
return economic;
}
public void setEconomic(int economic) {
this.economic = economic;
}
public int getSum() {
return sum;
}
public void setSum() {
this.sum = this.java+this.html+this.economic;
}
public int getAvg() {
return avg;
}
public void setAvg(int avg) {
this.avg=this.sum/1;
}

//重写toString
public String toString(){
String m="\t"+this.on+"\t"+this.name+"\t"+this.age+"\t"+this.java
+"\t"+this.html+"\t"+this.economic+"\t"+"\t"+this.sum+"\t"+this.avg;
return m;
}
}
------------------------------------------------------------------
主程序


public class test_11 {  
public static void main(String[]args){
//创建一个对象
Student stu=new Student();
stu.setOn(0);
stu.setName("似花非花人");
stu.setAge(21);
stu.setJava(45);
stu.setHtml(78);
stu.setEconomic(100);
stu.setSum();

System.out.println("\t编号\t姓名\t年龄\tjava\thtml\teconomic\t总分\t平均分");
System.out.println(stu);
}
}
//不知为何,stu.setAvg()无法执行。


------------------------------------------------------------------------------


创建Student类
class Student {
//封装属性
private int on;
private String name;
private int age;
private int java;
private int html;
private int economic;
private int sum;
private int avg;

//约束方法 取值和赋值
public void setOn(int on){
//赋值
this.on=on;
}
public int getOn(){
//取值
return this.on;
}
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 int getJava() {
return java;
}
public void setJava(int java) {
this.java = java;
}
public int getHtml() {
return html;
}
public void setHtml(int html) {
this.html = html;
}
public int getEconomic() {
return economic;
}
public void setEconomic(int economic) {
this.economic = economic;
}
public int getSum() {
return sum;
}
public void setSum() {
this.sum = this.java+this.html+this.economic;
}
public int getAvg() {
return avg;
}
public void setAvg(int avg) {
this.avg=this.sum/1;
}

//重写toString
public String toString(){
String m="\t"+this.on+"\t"+this.name+"\t"+this.age+"\t"+this.java
+"\t"+this.html+"\t"+this.economic+"\t"+"\t"+this.sum+"\t"+this.avg;
return m;
}
}
---------------------------------------------------------------------------------------------
//管理学生的一个Admin类
public class Admin {
String m="\t编号\t姓名\t年龄\tJava\thtml\teconomic\t总分\t平均分";
public void print(Student[] arr){
System.out.println(m);
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
public boolean exist(int on,Student stu){//判断学生是否存在
if(stu!=null){
if(stu.getOn()==on){
return true;
}else{
return false;
}
}
return false;
}
public void create(String name,int age,Student[] arr){
//添加学生方法

Student stu=new Student();
stu.setName(name);
stu.setAge(age);
int i=this.setIndex(arr);
stu.setOn(i);
if(i==99999){
System.out.println("学生人数无法添加");
}else{
arr[i]=stu;
}
arr[i]=stu;
}
public int setIndex(Student[] arr){
//返回为空的下标。
for(int i=0;i<arr.length;i++){
if(arr[i]==null){
return i;
}
}
return 99999;
}
public void select(int on,Student[] arr){
//查询方法
System.out.println(m);
for(int i=0;i<arr.length;i++){
if(this.exist(on,arr[i]==true)){
System.out.println(m);
System.out.println(arr[i]);
return;
}
}
}
System.out.println("不存在这个学生");
}
public void update(int on,String name,int age,Student[] arr){
//更新学员信息
for(int i=0){}


}
}
------------------------------------------------------------------------------------------
主程序
import java.util.*;
public class test_11 {   //主程序
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请定义人数");
//定义数组,数组长度为接收的学生数
while(true){
Student[] stuArr=new Student[in.nextInt()];
Admin adminStu=new Admin();
System.out.println("你要执行的功能:");
System.out.println("10:添加一个学生");
System.out.println("11:查找一个学生:");
System.out.println("12:根据学生编号更新学生基本信息");
System.out.println("13:根据学生编号删除学生");
System.out.println("14:根据编号输入学生各门成绩");
System.out.println("15:根据某门成绩进行排序");
System.out.println("16:根据总成绩排序");
System.out.println("99:退出系统");
int number=in.nextInt();
if(number==10){
System.out.println("请输入学生姓名:");
String name=in.next();
System.out.println("请输入学生年龄");
int age=in.nextInt();
adminStu.create(name,age,stuArr);//接收学生
adminStu.print(stuArr);
}else if(number==11){
System.out.println("执行查找学生基本信息");
System.out.println("请输入学生标号");
int on=in.nextInt();
adminStu.select(on,stuArr);
}else if(number==12){
System.out.println("执行更新学员的基本信息");
System.out.println("请输入学员的编号");
int on=in.nextInt();
System.out.println("请输入学生姓名");
String name=in.next();
System.out.println("请输入学生年龄");
int age=in.nextInt();
admitStu.update(on,name,age,arr);
}
}
}
}  


总结


这次作业写的糟糕。很多内容看不懂。分析原因,可能是到边际递减了。昨天调整一整天,今天玩耍一天,仍然不能恢复。什么是边际递减?是说一种要素不断投入,其他要素并未等比例投入,多投入一单位要素,总收入并未相应增长。生产者倾向于减少投入。放到这个例子上,其他因素并未明显变化,而学习内容明显减少,时间也减少,效果不如之前。边际成本不等于边际收入,我看一小时的书,感觉收获很少。
如何验证?
其他要素没有明显变化,我不再投入了。就比如我吃馒头,一直吃,一直吃,吃饱了,我就不吃了。从吃到不吃,这是一个边际变化,吃最后一个馒头就是边际成本,这个馒头达到的效果就是边际收入。边际成本大于边际收入,行为人就不吃了。边际产量递减定律的使用,要看其他因素是不是变化了。不然就是需求定律。


想到上将兄的一个例子,他写文章,什么时候企业会选择多元化?套套逻辑的说,当一个业务的收入达到边际成本等于边际收入的时候,企业就会转向多元化。然后放入具体例子,一个厨师,若烧一个菜收入是10元,两个菜是18元,烧三个菜是24元。若切一个菜的收入是7元。这个厨师会怎样选择,这个厨师会选择烧两个菜切一个菜,而非烧三个菜。厨师从烧菜到切菜就是多元化的选择。拓展到一个公司是不是这样呢?当公司在一个业务中获得的收入开始边际递减,边际收入递减到不如做其他事情的收入时,边际上,厨师烧三个菜的总收入不如烧两个菜切一个菜的时候,企业就会转向多元化。然后用来分析乐视的多元化。乐视多元化的内容,在上将兄看来,跨行的成本很大,很多业务没有上头成本。和别人竞争有什么优势呢?然后例举Google一类的大公司。上将兄说,他们把本行业的钱赚完了,然后找有上头成本的行业多元化。Google的各种人工智能,都是和算法有关,Google有上头成本。


上将兄的解释重点是,企业什么时候走多元化?一个是边际递减到了什么时候。这个要看具体局限怎样。一个是看有没有上头成本。我想起来齐白石从木匠转行国画。是边际递减吗?铁定是,边际上,画画收入比木匠生意赚的多。
他从做粗家具到精细家具,在当地小有名气,结识一些知识分子,学着画画写诗刻章,学了一段时间,发现自己画画也能卖钱,而且比木匠生意赚的多。就转行了。


再看不到学Java的收入,再多的承诺决心都是没用的。


《初学Java》系列七


第六章(三)


详解学生管理系统


上篇写的马虎,不惯使用myeclipse,这次使用记事本。有个同学很有本事,能用Java写一个记事本。代码我要过来了,但是看不懂。哈哈。


首先说功能,这个是第一章讲到的内容,在《系列四》的结尾提到过:【给了一个成品的结果,然后分析这个结果是怎么做出来的。令我想到第一章讲过的用程序解决问题的思路。


课本上是这样讲的,软件开发过程:问题定义→设计解决方案→编写程序→测试、运行。


什么是问题定义?课本上说,这个阶段要弄清楚以下几个问题;(1)程序的目标是什么?需要程序解决什么问题?应该实现的功能是什么?(2)可能需要输入哪些数据?(3)数据具体的处理过程和要求是什么(4)程序可能的输出数据是什么?表现形式是什么?



随意的挥洒一下,我要做饭,首先要想明白我做什么饭,然后我用什么做,我的材料放在哪里,我想做成什么样的结果,是稠一些,还是稀一些,是淡一些还是咸一些,是一个人的分量还是三个人的分量,这些都要想明白,尽管最后的饭仍然可能难吃。但是这些程序都是需要的。每一个程序都是有成本的,在什么情况下用怎样的程序代码成本最低。就好像早上不蒸米也不下面条,中午不吃稀饭。各自的成本不同,早上刚睡醒,胃口不佳,吃少量食物便满足需求,若是蒸米,必定是吃不完,而且蒸米还要配菜,必定早起,这样费时费力却吃的不多,意味机会成本很大,所以很少有人早上不蒸米。同样,有些代码也能实现相同效果,但是代码效率低,复杂不安全,费时费力效果不好,机会成本高。所有程序员都是追求代码简洁并且效果满意。我对自己没有这个要求,原因简单,我没有工作压力,写错没有惩罚,写对没有奖励。追求简洁代价大,非我这凡夫所能处理。如果我有好老师,如果我有好课本,如果我有好论坛,如果我能欣赏代码的艺术,如果我才思敏捷,人生就爽歪歪了。
代码实现的功能,以及如何实现的,不能放入价格理论,但是人选择怎样的代码,是人的选择,可以严格的放入价格理论。内容越多,放的越多。我想到上将兄解释的按需定制在软件行业的应用。和软件行业有些关系。


【软件行业也有这样的情况。软件也有“品牌”的和“组装”的。个人软件一般都是“品牌”,企业软件多为“组装”。除了通用的像office以外,企业软件有很多是定制开发,因为各个企业生产流程不同,就是同一个企业2个不同的分厂,同一个生产环节,流程可以相同也可以不相同。对于相同的部分,可以买通用的像office、ERP财务模块的软件,但除此以外,大部分的软件都需要按需开发。所以企业软件多数不提供下载试用(给别人做的和跟你要的不一样,试了也没用),没有盗版,因为盗了也用不了(像SAP这样的,不经专门培训,甚至连安装都不会装)。比如ERP除了财务以外,其他模块买下来以后还得根据客户需求再做二次开发,或者买其他软件作为数据接口,费用一点也不低,光前期POC,吵需求就要吵上好几个月,如果事先不吵清楚,后续开发就是边开发边返工。很多程序员加班其实都是需求问题,前期不调研清楚,后续只能依靠程序员增加工作量弥补。搞得程序员特别辛苦,客户也不满意(因为会延期)。这些做按需开发的公司,多数是小公司,虽然也有IBM这样的大公司,但他们的职能更像是个中介,接下生意以后再外包给小公司。客户一般也了解这种情况,小项目就找小公司,大项目找大公司做中介的主要目的,一是因为需要的人太多(驻厂开发人员占满一个层面是常有的事),二是防止小公司跑路,项目烂尾。
有些公司项目定制需求特别大,比如intel,干脆就连外包定制都不做,直接买一个开发团队,自己开发自己的软件。也有些公司因为和小公司长期合作,逐步发现自己的需求很特别,不适合外包开发,那么就把先前合作比较愉快的外包团队,直接收购变成自己的软件开发部,专做公司内的定制开发。
由此还引申出来一个行业,有的公司,专门接别人因前期需求调研不明或因技术问题导致最后烂尾的项目。这些项目急于上线,但是上家公司做不下去,所以接手的公司,收费特别高。


2015年8月7日:“按需定制定理”的一般化(http://tieba.baidu.com/p/3952640703)】


上将兄解释的是很大的内容。我没有这个本事。


好,我们来看此成品的效果。
我们把学生管理系统看成一个产品。我还是用另外一种语言来描述比较好。我们在生产一件产品,在生产之前,我们要知道我们是怎样生产的,生产出来的效果如何,产品是否合格,生产的成本是否最低。去过工厂的同学都知道,产品的生产都是有规范流程的,流水线生产,每个过程都是老板规定好的,工人只需要执行。同样的,现在我们是老板,是女娲,要自己规定自己产品的样子。我们应该如何描述我们的产品呢?
同样一件产品,不同的描述方法,有不同的效果。不同的销售员有不同的工资,可能就是在描述方法上有了区别。我只是猜测,没有验证。
我按照我的方式描述,效果如何,试试就知道了。
(1)、“请定义学生的人数”
分析这句话背后的含义,在之前章节中提到过,后面还要声明一个扫描仪接收数据。尝试写下代码,
import java.util.*;
public class a{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("请定义学生的人数:");
int renshu=in.nextInt();
}
}//代码简单,就不再解释了。


(2)、“请选择你要执行的功能:
10......
11..
12.....
13....
14....
15....
16....
99...

这段代码表示这个程序所能实现的功能,10 11 12......这些是功能的序号,我们提供的功能就是这些提示,用户操作就是输入相应的代码。程序根据代码指示完成之后的内容。这一串本来是个System.out.println(),但是背后有内容的。这个是下一个过程实现的。


(3)、比如输入编号10
“请输入学生的姓名:”


似花非花人


“请输入学生的年龄:”


21


“编号 姓名 年龄 java 总分 平均分”
“0 似... 21 0 0 0


“请选择你要执行的功能:
10......
11..
12.....
13....
14....
15....
16....
99...

这个过程就很多了,如果是按照以前办法,也是可以实现,在《系列四》中也讲过一个学生管理系统,但是没有讲到封装,也没有讲到类和对象。当时是这样处理的:

import java.util.*;
public class A4{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.println("请输入学生人数:");
int renshu=in.nextInt();//声明变量renshu存储学生人数
System.out.println("请输入课程数目:");
int courseNum=in.nextInt();//声明一个变量courseNum存储课程数目
String[] name=new String[renshu];//声明数组name用来存储学生姓名
String[] course=new String[courseNum];//声明数组course用来存储课程名称
int[][] number=new int[renshu][courseNum];声明一个number的二维数组,数组大小用户定
  //后面打印成绩表用到的
int[] sum=new int[renshu];//声明一个变量int数组用来存储sum,总分
int[] avg=new int[renshu];//声明一个变量avg数组,存储平均分
String[] str=new String[renshu];//声明str的数组,长度是renshu,存储数据内容sri[i]
/*用来循环输入课程名称*/
for(int i=0;i<course.length;i++){
System.out.println("请定义第"+(i+1)+"门课程名字:");
course[i]=in.next();//把接受的数据存储在course数组中。
}
/*用来录入学生课程成绩*/
for(int i=0;i<renshu;i++)
{
int S=0;//声明一个变量,并赋初始值0
System.out.println("请输入第"+(i+1)+"学生姓名:");
name[i]=in.next();//接受的姓名存储在name数组中
String str11="";//声明一个str11的变量,但是什么也没有 。
for(int j=0;j<courseNum;j++){
System.out.println("请输入学生"+name[i]+course[j]+"成绩");
number[i][j]=in.nextInt();//用来存储特定学生的特定成绩
//{{45,45,45...}{45,45,45...}{}.....}
//打印就要换行了。
S+=number[i][j];//加总输入的学生成绩,+=是叠加。
str11+=number[i][j]+"\t";//累加求和?str11=str11+number[i][j]
//也是为了后面打印效果。
}
sum[i]=S;//这是赋值成为总分
avg[i]=S/courseNum;
str[i]=name[i]+"\t"+str11+sum[i]+"\t"+avg[i];//
}
for(int i=0;i<str.length-1;i++){ //循环交换,一个学生又一个学生
for(int j=0;j<sum.length-1;j++){
if(sum[j]<sum[j+1]){
int t1=sum[j]; String t2=str[j];
sum[i]=sum[j+1]; str[j]=str[j+1];
sum[j+1]=t1;  str[j+1]=t2;
}
}
}
/*效果输出*/
System.out.print("学生");
for(int i=0;i<course.length;i++){
System.out.print("\t"+course[i]);//输出课程名称
}
System.out.print("\t总分\t平均分\t排行榜");//输出标题
System.out.println();
for(int i=0;i<renshu;i++){
System.out.println(str[i]+"\t第"+(i+1)+"名");
}
}
}


我们来分析思路,一步一步分析。我不想一步一步写代码了。这次主要看思路
1.让用户定义学生人数。renshu=in.nextInt()
2.让用户输入科目数目。courseNum=in.nextInt()
3.声明一个数组用来保存学生姓名。String[] name
数组的长度是学生renshu
4.声明一个数组用来存储科目名称 String[] course
长度是course
5.循环让用户输入科目名称。循环条件是i<courseNum
科目名称存到数组course[]
6.循环让用户输入学生姓名。循环条件是j<renshu
学生姓名存储到数组name[]
7.输入每个学生对应每科成绩,用嵌套循环实现。
大循环是6,小循环输入成绩,判断条件是i<courseNum
8.声明数组存储成绩
学生 经济学 操作系统   数据库   平均分   排行榜
似花非花人 90   45     45     60    第一名


壁虎老师 0    0         0      0     第二名


{90,45,45,60}这是一个数组,说明是用二维数组接收成绩。
定义二维数组,number=new int[renshu][course]比如90的位置是number[0][0]因为数组的坐标是从0开始的。
number={{90,45,45},{0,0,0},{},......}
平均分和排行榜不是一个数组。


9.打印标题
学生 经济学 操作系统   数据库   平均分   排行榜
学生、课程名与平均分和排行榜不在一个程序体中。
它们不在任何循环中,而是在入口处。
①在学生标题下出现学生姓名。然后姓名和成绩在同一行,加入8数组。
②计算平均分和排行榜。然后平均分下面出现分数和排行榜。并非8的数组。



代码注释相比较《系列四》,我重新注释一遍,更清楚了。这段代码效果和新产品的打印效果是一样的。但是只是新产品编号10的功能。由于没有使用类,封装,对象的内容,代码长,功能少。对程序员来说,机会成本高。好,我们接着分析下一个功能。


(5)输入编号14
“请输入学生成绩”
“请输入学生的编号”
0
“请输入似花非花人Java成绩:”
45


“编号 姓名 年龄 java 总分 平均分”
“0 似... 21 45 45 45


“请选择你要执行的功能:
10......
11..
12.....
13....
14....
15....
16....
99...

(6)循环上面的操作
“编号 姓名 年龄 java 总分 平均分”
“0 似... 21 45 45 45
“1 壁虎.. 22 100 100 100”
“......”
“......”
“请选择你要执行的功能:
10......
11..
12.....
13....
14....
15....
16....
99...

还有11 12 13 14...功能没有展示。我们可以把这个产品叫做成绩单2.0,把《系列四》中的产品叫做成绩单1.0,很明显内容增加很多,能够满足客户更多的需求,对程序员来说,做出这样的程序,成本也增加很多,若用1.0版本方法写代码,程序员机会成本很大,因为用面向对象写能够更便捷的实现这些功能。面向对象的思想谁想出来的?不知道,拿过来用便是,知识的积累一代又一代人累加的。我们不可能知道天下间所有知识,也不需要知道。因为知道的代价太大了。比如int,什么意思?数据类型→整型,至于这个数据类型谁创造的,怎么创造的,后来又是怎样发展的,没必要知道。前人种树,后人乘凉。我们只管乘凉。总之,我们知道用面向对象能够写出一个2.0版本。


深入对比1.0版本与2.0版本的思路


对程序员来说,
第一种办法,在main方法中定义输入什么的、字符串、输出。写出很多过程。写出一个过程,再写一个过程。


第二种办法,把这些功能当成对象,成批处理。


有什么区别?
第二种是把实现的功能当成对象,一个类。成批处理。与第一种方法比较,要放在局限条件下比较,数据足够多的情况下,1、修改数据。2、添加修改功能。3、安全。做到这三点,二者的成本差异明显。


好,这次分析到这里,下次处理这些功能具体代码如何,那就是技术内容了。肯定不如现在写的爽。


《初学Java》系列八


第六章(四)


学习过程中,和同学有过一些讨论。我现学现卖,拿出Javase的知识,同学一眼看出是Javase,指出java内容远非Javase,有更多内容是我未曾了解的。可能以后也不能了解。我把Java称为迷雾森林。线路难找。我欲何为,无人知晓。远不如经济学来的清晰,经济学虽难,重逻辑重推理,但重点来的清楚明白。分析时,把例子严格放入价格理论,谁是价格,谁是需求量,哪些其他因素不变。提出一个假说,然后验证,出错便再提。来的清楚明白。经济学内容确实多,多的很,令人目不暇接。但是重点清楚明白。


我还没有拿住重点。学的吃力,常有奇怪想法,自己也觉好笑。我的提问,显的无知透顶。

兵哥见解


w 21:39:52
是我刚上大一学java时候随手写的


w 21:41:06
只是布局选择器的一些简单的应用而已


w 21:43:12
我这两年写的基本都是web针对的一些东西,需要搭载一些平台或者和其他现成的东西对接才有效果,两年前写的一些游戏,程序都找不到了


w 21:51:42
现在觉得找不到也无所谓,忘了算法之类的可以直接百度找,忘了用法之类的可以直接看源码


似花非花人 22:34:48
[图片]


w 22:35:15
不是


w 22:36:31
jdbc是链接数据库的比如你学的sqlsever mysql等


w 22:37:06
web说的是javaweb 及javaee体系


似花非花人 22:38:31
这张图的哪个部分?


w 22:38:45
没有


w 22:39:00
你写的所有东西只是javase


w 22:41:30
比如jdbc,这是se里面的内容,只是通过java来打开关闭数据库和向数据库里面直接插入sql语句


w 22:43:01
但是javaee里面数据库访问用的hibernate框架,就是通过映射关系把类看成表,成员变量看成元组,包看成数据库,直接面相对象的操作数据库,根本不是一个层面的东西


w 22:46:46
比如你的青果教务管理系统,八成用的是javaweb,就是在web进行数据操作和数据反馈,web体系包含html,js,jq,xml,json等已经不只是java这门语言了


w 23:05:42
一个是直接照搬,一个是从零创造,就这么简单




  】
好,开始本次的内容。


把要实现的功能翻译成代码语言。
Student类
定义一个类或是创建一个类,分为两部分,一个是属性,一个是行为。属性可以无穷无尽,行为也是如此。我们只需要创造自己需要的内容,适可而止。
public class Student{
//属性
//private 封装,1.0版本,无创建类,也无封装操作
private int on;//定义属性名on
private String name;//定义属name
private int age;//定义属性age
private int java;//属性java
private int c_char;//属性c#
private int html;//属性html
private int sql;//属性sql
private int sum;//属性总分sum
private int avg;//属性平均分avg


//封装的属性,相当于上了一把锁,或是设置一条迷宫,外界要访问,
//要有一把钥匙或知道地图。
//设置方法相当于提供一把钥匙或是地图


//先定义给数值的方法 public是所有对象都能公共使用这个方法。
//setOn和getOn是方法名,主程序全靠方法名调用


public void setOn(int on){

//赋值,首先要明白谁的值赋给了谁?
//主程序中创建某对象,主程序中把某对象的值传给Student类
//栈中对象和堆中某对象的类,皆有特定值的地址,方可调用
//this.On指此值给了当前对象
//同一味药可用在不同病人,只要病一样 强调药的一般化、普适性
//注意参数类型
this.on=on;
}

//再定义取值方法

public int getOn(){


//取值就是调用。调用的数值是之前所赋的值
return this.on;
}

//其他属性原理一样。

public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age=age;
}
public int  getAge(){
return this.age;
}
public void setJava(int java){
this.java=java;
}
public int getJava(){
return this.java;
}
public void setC_char(int c_char){
this.c_char=c_char;
}
public int getC_char(){
return this.c_char;
}
public void setHtml(int html){
this.html=html;
}
public int getHtml(){
return this.html;
}
public void setSql(int sql){
this.sql=sql;
}
public int getSql(){
return sql;
}
public void setSum(int sum){
this.sum=sum;
}
public int getSum(){
return this.sum;
}
public void setAvg(int avg){
this.avg=avg;
}
public int getAvg(){
return this.avg;
}


//上述方法专门为private服务
//属性有了,行为还没有
   【Student类的行为(成员方法)的效果是什么?我们只有从该效果去设置该行为。我们想要得到什么样的效果呢?在《系列七》提到过效果,如下:


“编号 姓名 年龄 java 总分 平均分”
“0 似... 21 45 45 45
“1 壁虎.. 22 100 100 100”
“......”
“......”


这些效果是在主程序中的对象调用Student类中的行为(成员方法)的输出结果。
我们需要一个toString方法。在《系列五》中讲过toString的用法,当时是这样讲的:
toString
默认输出的一个类。
class Cat{


}
/*public class test{
public static void main(String[]args){
String name=new String("你好");
System.out.println(name);//自动调用toString方法。
System.out.println(name.toString());
}
}*/
没有定义就调用的情况
/*public class test{
public static void main(String[]args){
Cat one=new Cat();
System.out.println(one.toString());//输出的是哈希码值
}
}*/
定义toString再调用
class Cat{
String name;
int age;
public String toString(){
return"姓名"+name+"年龄"+age;
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat();
one.name="小猫咪";
one.age=123456789;
System.out.println(one.toString());
System.out.println(one);
}
}
这里要想明白,在1.0版本时候,对默认输出毫不在意,在引用类之后,如果不定义就默认输出,效果是哈希码值。可能还是不懂,可以这样想,1.0版本和2.0版本在输出的时候有什么不同?多了一个类,这个类是自己定义的。这个就是局限了。这个局限变化导致的效果是默认输出值不再是我们想要的。我们要在自己创造类的局限下,使用自己想要的方法(行为)】

//我们要输出的是对象的属性的具体的数据
//这个方法是返回无参方法,返回内容给了toString

public String toString(){

//声明一个String,名msq,赋值想要的输出结果
String msq="\t"+this.on
+"\t"+this.name
+"\t"+this.age
+"\t"+this.java
+"\t"+this.c_char
+"\t"+this.html
+"\t"+this.sql
+"\t"+this.sum
+"\t"+this.avg;

//返回语句,因为是返回方法,要有返回语句,没有返回语句,就没有返回内容


return msq;
}
}


本次就写这么多。写好了Student类。下次写主程序。


(文中提到public和private,在《Collins》中
public,1、relating to the people as whole 2.provide by the goverment 3.open to all .....
private,1.not for general or public use 2.not publicly known ......


这令我想到了私用品和共用品的概念,什么是私用品什么是共用品?私用品Private Goods ,指的是我享有你便不能再享有这物品的全部。而共用品Public Goods 指我享有并不影响其他人同样使用。比如,电影,你看的同时,我也能看,我们相互间不影响,还有歌声,你能听,我也能听,我们之间没有损害。但,一个苹果,你吃了一口,我就不能再吃这苹果的全部,苹果就是私用品,还有手机、电脑、书桌、床等等,一个人使用另外一个人就不能使用物品的全部,这个就是私用品了。


我之前没有理解区别二者概念有何用处。当我们定义了私用品后,便可以否决“剪刀分析”。在分析市场的时候,会分析到一个均衡价格,说的是市场上所有需求者的需求曲线和供应者的供给曲线相交,相交的点是均衡点,此时市场均衡。这样的分析问题出在哪里?我们先分析私用品的市场,私用品的市场需求曲线是个别需求者向右横加而成。什么是向右横加?画无数条需求曲线,在同一个价格下,不同需求者的需求量加到一起,就是总需求量,这个总需求量就是个别需求者向右横加而成。市场的需求曲线的含义,所有需求者的边际用值与总需求量的关系。什么是边际用值?就是边际上物品的价值。市场局限下就是市价。与总需求量的关系,边际用值下降,总需求量就下降,边际用值下降是需求曲线,右下方倾斜,那么市场需求曲线也是右下方倾斜了。


用例子辅助推理,海滩上的买得起钱贝壳是一个没有生产的市场,贝壳是私用品。在没有生产的局限下,我们来分析物品的市场需求,分析的是买得起钱的贝壳,而非不值钱如沙土的东西。会发生怎样现象?贝壳值钱,需求者络绎不绝。在市场上,每个需求者看市价低于自己的边际用值,就多买入。见高于自己边际用值,便卖出。这解释了为什么会有买卖行为。用需求者的边际用值和市价对比。之后又发生了什么现象呢?每个需求者的买卖行为,对市价都会有轻微影响。每个人的用值都表现在了市价上。1、市价为什么起伏波动?这里的解释是每个需求者用值不同,于是买入或出售自己的产品,从而影响了市价。我们还可以更深入的用供求理论解释,供不应求下,生产者和需求者为自利,生产者涨价,需求者减少需求量;供过于求,供应者降价,需求者多买。通过价格来调整供求关系,价格反映的是物品的供求关系。2、市价只有在市场制度下才能调整供求关系。


每个需求者以自己边际用值和市价衡量,进而选择买入或卖出后,边际用值就等于市价,当市价不变是,所有需求者的边际用值相等。如果每个需求者的边际用值不相等,市场就不会均衡,市价就一直在变化。轻微变化也是变化。


同样的,市场的供给曲线也是市场中的无数供应者看着自己的边际用值选择供应。两条曲线画在一张图里,会有一个交点,这个交点就是市价。但是没有人知道这个交点在哪里,这个交点无从验证。因为我们知道每个供应者和需求者的边际用值是不同的,什么时候相同无从验证。【这里有个要点,在没有生产的局限下,市场的供应曲线是竖直的。需求曲线是右下方倾斜。每个人边际用值不同,需求量就不同,横向加总的市场需求曲线就一直变化。】


现在我们知道市价是如何决定了,我们再来分析“剪刀理论”的问题,它说,市价是市场需求曲线和供应曲线相交产生的。而我们说,无数需求者和供应者为自利,不约而同争取自身边际用值和市价相等,促成了市场需求曲线和市场供给曲线相交之价。这两个角度正好相反,一个说是先相交,然后有了市价。一个是说先有了市价,然后曲线相交。

http://blog.sina.com.cn/s/blog_47841af7010003zt.html(灯塔的故事)
http://zhangwuchang.blog.sohu.com/174329167.html(剪刀比喻误导)



《初学Java》系列九


第六章(五)


主程序1


思路流程
public class test{
public static void main(String[]args){
System.out.println("\t编号\t姓名\t年龄\tjava\tc# \thtml\tsql\t总分\t平均分");

//这只有标题,并未输出对象 我们要的是toString里面的内容
//主程序中输出的内容是Student类中的内容才行。创建对象、声明、赋值、调用步骤一个都不能少。
}
}


public class test{
public static void main(String[]args){


//在Student类中创建对象stu


Student stu=new Student();


//调用类中方法并赋值


stu.setOn(0);
stu.setName("似花非花人");
stu.setAge(21);
stu.setJava(45);
stu.setC_char(0);
stu.setHtml(78);
stu.setSql(45);


//总分和平均分是算出的,并非设置,应该在Student类中修改
//修改见下文


stu.setSum();
stu.setAvg();


System.out.println("\t编号\t姓名\t年龄\tjava\tc# \thtml\tsql\t总分\t平均分");


System.out.println(stu);
}
}
-------------------------------------------------------------------------------------------------
Student修改结果
public class Student{
//属性
//private 封装,1.0版本,无创建类,也无封装操作
private int on;//定义属性名on
private String name;//定义属name
private int age;//定义属性age
private int java;//属性java
private int c_char;//属性c#
private int html;//属性html
private int sql;//属性sql
private int sum;//属性总分sum
private int avg;//属性平均分avg


//封装的属性,相当于上了一把锁,或是设置一条迷宫,外界要访问,
//要有一把钥匙或知道地图。
//设置方法相当于提供一把钥匙或是地图


//先定义给数值的方法 public是所有对象都能公共使用这个方法。
//setOn和getOn是方法名,主程序全靠方法名调用


public void setOn(int on){

//赋值,首先要明白谁的值赋给了谁?
//主程序中创建某对象,主程序中把某对象的值传给Student类
//栈中对象和堆中某对象的类,皆有特定值的地址,方可调用
//this.On指此值给了当前对象
//同一味药可用在不同病人,只要病一样 强调药的一般化、普适性
//注意参数类型
this.on=on;
}

//再定义取值方法

public int getOn(){


//取值就是调用。调用的数值是之前所赋的值
return this.on;
}

//其他属性原理一样。

public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age=age;
}
public int  getAge(){
return this.age;
}
public void setJava(int java){
this.java=java;
}
public int getJava(){
return this.java;
}
public void setC_char(int c_char){
this.c_char=c_char;
}
public int getC_char(){
return this.c_char;
}
public void setHtml(int html){
this.html=html;
}
public int getHtml(){
return this.html;
}
public void setSql(int sql){
this.sql=sql;
}
public int getSql(){
return sql;
}
public void setSum(int sum){
this.sum=this.java+this.c_char+this.html+this.sql;
}
public int getSum(){
return this.sum;
}
public void setAvg(){
//删去了参数。否则主程序重要传参数。


this.avg=this.sum/4;
}
public int getAvg(){
return this.avg;
}


//上述方法专门为private服务
//属性有了,行为还没有
  

//我们要输出的是对象的属性的具体的数据
//这个方法是返回无参方法,返回内容给了toString

public String toString(){

//声明一个String,名msq,赋值想要的输出结果
String msq="\t"+this.on
+"\t"+this.name
+"\t"+this.age
+"\t"+this.java
+"\t"+this.c_char
+"\t"+this.html
+"\t"+this.sql
+"\t"+this.sum
+"\t"+this.avg;

//返回语句,因为是返回方法,要有返回语句,没有返回语句,就没有返回内容


return msq;
}
}




1.0版本成绩表


import java.util.*;
public class A4{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.println("请输入学生人数:");
int renshu=in.nextInt();//声明变量renshu存储学生人数
System.out.println("请输入课程数目:");
int courseNum=in.nextInt();//声明一个变量courseNum存储课程数目
String[] name=new String[renshu];//声明数组name用来存储学生姓名
String[] course=new String[courseNum];//声明数组course用来存储课程名称
int[][] number=new int[renshu][courseNum];声明一个number的二维数组,数组大小用户定
  //后面打印成绩表用到的
int[] sum=new int[renshu];//声明一个变量int数组用来存储sum,总分
int[] avg=new int[renshu];//声明一个变量avg数组,存储平均分
String[] str=new String[renshu];//声明str的数组,长度是renshu,存储数据内容sri[i]
/*用来循环输入课程名称*/
for(int i=0;i<course.length;i++){
System.out.println("请定义第"+(i+1)+"门课程名字:");
course[i]=in.next();//把接受的数据存储在course数组中。
}
/*用来录入学生课程成绩*/
for(int i=0;i<renshu;i++)
{
int S=0;//声明一个变量,并赋初始值0
System.out.println("请输入第"+(i+1)+"学生姓名:");
name[i]=in.next();//接受的姓名存储在name数组中
String str11="";//声明一个str11的变量,但是什么也没有 。
for(int j=0;j<courseNum;j++){
System.out.println("请输入学生"+name[i]+course[j]+"成绩");
number[i][j]=in.nextInt();//用来存储特定学生的特定成绩
//{{45,45,45...}{45,45,45...}{}.....}
//打印就要换行了。
S+=number[i][j];//加总输入的学生成绩,+=是叠加。
str11+=number[i][j]+"\t";//累加求和?str11=str11+number[i][j]
//也是为了后面打印效果。
}
sum[i]=S;//这是赋值成为总分
avg[i]=S/courseNum;
str[i]=name[i]+"\t"+str11+sum[i]+"\t"+avg[i];//
}
for(int i=0;i<str.length-1;i++){ //循环交换,一个学生又一个学生
for(int j=0;j<sum.length-1;j++){
if(sum[j]<sum[j+1]){
int t1=sum[j]; String t2=str[j];
sum[i]=sum[j+1]; str[j]=str[j+1];
sum[j+1]=t1;  str[j+1]=t2;
}
}
}
/*效果输出*/
System.out.print("学生");
for(int i=0;i<course.length;i++){
System.out.print("\t"+course[i]);//输出课程名称
}
System.out.print("\t总分\t平均分\t排行榜");//输出标题
System.out.println();
for(int i=0;i<renshu;i++){
System.out.println(str[i]+"\t第"+(i+1)+"名");
}
}
}
--------------------------------------------------------------------------------------------------
主程序2
用数组淘汰主程序1
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("---请定义学生人数---");

//为什么要定义学生人数?学生人数就是数组长度
//谁的数组?在1.0版本,数组很多,renshu是很多数组长度
//在2.0版本,直接声明一个Student的数组,用来存无数对象
//存的是用Student类创建的对象 其他对象不能进来


Student[] stuArr=new Student[in.nextInt()];

//提示产品的功能 尚未实现


System.out.println("你要执行的功能:");
System.out.println("10:添加一个学生");
System.out.println("11:查找一个学生:");
System.out.println("12:根据学生编号更新学生基本信息");
System.out.println("13:根据学生编号删除学生");
System.out.println("14:根据编号输入学生各门成绩");
System.out.println("15:根据某门成绩进行排序");
System.out.println("16:根据总成绩排序");
System.out.println("99:退出系统");




}
}


总结,现在我们实现了什么功能?我们创建了一个Student类,然后在主程序中声明了一个Student数组,这些功能现在看不到的。运行主程序2,什么功能也没有,但写好了很多,比如成绩,总分,平均分,现在都可以声明并接受的。在《系列七》提过效果,输入编号,选择功能,我们现在只是有了一个学生基本信息的功能,但是我们查找学生的功能,修改学生信息的功能,删除学生信息的功能,排列总分的功能都没有实现。如何实现下一个功能?功能与功能之间的转接在代码中是怎样实现的?


这些功能是对学生进行管理,就再创建一个管理学生的类。Student类是学生类,学生的属性、行为,然后打印出来如此这般的效果,并没有管理学生,也并没有提到这些功能。现在的思路是,一个类是创建学生,一个类是管理学生。这样能够提供产品的可维护性和可拓展性。我并不知道什么是可维护性也不知道什么是可拓展性。大概就是减少了程序员修改代码的机会成本。数据量很大,1.0版本是不是要修改很长时间?同样局限下,2.0版本修改时间会变短。不然就不会产生2.0了。




《初学Java》系列十


第六章(六)


都写到系列十了?现阶段,此产品对我而言内容很多,我要细致的分析它。于是分批处理。


上次讲到要创建一个类管理学生功能
Admin类
来看我们的需求,我们是为了实现产品的功能,那么,这个类的属性和方法将会是什么?
a.添加学生的功能
添加到哪里?添加到Student[]数组中。


public class Admin{
//10功能添加学生 方法如下
//方法名为creat,三个参数,传入主程序内容但是地址在Student类
// Student数组名为arr
//在Student类中new一个对象,名为stu 调用Student类中的方法
//stu调用的方法是取值set,取过来值给了对象stu
//对象stu的值存在数组Student[]中


public create(String name,int age,Student[] arr){
Student stu=new Student();
stu.setName(name);
stu.setAge(age);

//还没有判断是否为空 要判断一下 方法在下面

int i=this.setIndex(arr);
stu.setOn(i);


//如果Student[]数组没有空位 方法会返回99999
//没有空位的处理

if(i==99999){
System.out.println("添加满额。");
}else{
arr[i]=stu;
}


}


//判断是否数组中是否有数据 同一个对象不能添加到同一个位置


public int setIndex(Student[] arr){

//判断数组中是否有对象数据
//循环判断数组中所有位置,就是遍历

for(int i=0;i<arr.length;i++){
if(arr[i]==nall){

//为什么返回i?此下标有空位,可以放入

return i;
}
}
return 99999;
}


}


这个类写好了,在主程序那边怎么调用呢?使用过程要解释。我们把主程序贴过来
并添加Admin类
主程序3
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("---请定义学生人数---");

//为什么要定义学生人数?学生人数就是数组长度
//谁的数组?在1.0版本,数组很多,renshu是很多数组长度
//在2.0版本,直接声明一个Student的数组,用来存无数对象
//存的是用Student类创建的对象 其他对象不能进来


Student[] stuArr=new Student[in.nextInt()];

//声明一个Admin类的对象,

Admin adminStu=new Admin();

//提示产品的功能 尚未实现


//死循环
while(true){
System.out.println("你要执行的功能:");
System.out.println("10:添加一个学生");
System.out.println("11:查找一个学生:");
System.out.println("12:根据学生编号更新学生基本信息");
System.out.println("13:根据学生编号删除学生");
System.out.println("14:根据编号输入学生各门成绩");
System.out.println("15:根据某门成绩进行排序");
System.out.println("16:根据总成绩排序");
System.out.println("99:退出系统");

//判断用户输入的编号
int number=in.nextInt();
if(number==10){


//adminStu是从Admin类中创建的对象
//调用方法create,赋值

System.out.println("请输入学生姓名:");
String name=in.next();
System.out.println("请输入学生年龄:");
int age=in.nextInt();


//stuArr是数组里面的内容 在Student类中是Java sql html c#
//添加学生
adminStu.create(name,age ,stuArr);
}else if(number==11){
System.out.println("执行查找功能");
System.out.println("请输入编号");
int on=in.nextInt();
adminStu.
}


//循环执行,把stuArr数组填满

for(int i=0;i<stuArr.length;i++){
if(stuArr[i]!=null){
System.out.println(stuArr[i]);
}
}



}
}
}


总结,主程序中adminStu.create( , , stuArr),把这些数值传到了Admin中,stuArr是在Student中创建的数组,我们是把这个数组传进去了吗?没有,我们传进去的是一个地址。把stuArr这个地址给了Admin中的arr


b.查找学生的功能


public class Admin{
//10功能添加学生 方法如下
//方法名为creat,三个参数,传入主程序内容但是地址在Student类
// Student数组名为arr
//在Student类中new一个对象,名为stu 调用Student类中的方法
//stu调用的方法是取值set,取过来值给了对象stu
//对象stu的值存在数组Student[]中
String msg="\t编号\t姓名\t年龄\tJava\tc#\thtml\tsql\t总分\t平均分";
public void print(Student[] arr){
System.out.println(msg);
for(int i=0;i<arr.length;i++){
System.out.prinln(arr[i]);//更新信息
}
}
public create(String name,int age,Student[] arr){
Student stu=new Student();
stu.setName(name);
stu.setAge(age);

//还没有判断是否为空 要判断一下 方法在下面

int i=this.setIndex(arr);
stu.setOn(i);


//如果Student[]数组没有空位 方法会返回99999
//没有空位的处理

if(i==99999){
System.out.println("添加满额。");
}else{
arr[i]=stu;
}


}


//判断是否数组中是否有数据 同一个对象不能添加到同一个位置


public int setIndex(Student[] arr){

//判断数组中是否有对象数据
//循环判断数组中所有位置,就是遍历

for(int i=0;i<arr.length;i++){
if(arr[i]==nall){

//为什么返回i?此下标有空位,可以放入

return i;
}
}
return 99999;
}

//实现查找学生功能的方法
//接受编号on和数组。因为从数组中找的
public void select(int on,Student[] arr){
System.out.println(msg);
for(int i=0;i<arr.length;i++ ){
if(arr[i].getOn()==on){
System.out.println(arr[i]);
return;
}
}
System.out.println("查无此人");
}




}


主程序4
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("---请定义学生人数---");

//为什么要定义学生人数?学生人数就是数组长度
//谁的数组?在1.0版本,数组很多,renshu是很多数组长度
//在2.0版本,直接声明一个Student的数组,用来存无数对象
//存的是用Student类创建的对象 其他对象不能进来


Student[] stuArr=new Student[in.nextInt()];

//声明一个Admin类的对象,

Admin adminStu=new Admin();

//提示产品的功能 尚未实现


//死循环
while(true){
System.out.println("你要执行的功能:");
System.out.println("10:添加一个学生");
System.out.println("11:查找一个学生:");
System.out.println("12:根据学生编号更新学生基本信息");
System.out.println("13:根据学生编号删除学生");
System.out.println("14:根据编号输入学生各门成绩");
System.out.println("15:根据某门成绩进行排序");
System.out.println("16:根据总成绩排序");
System.out.println("99:退出系统");

//判断用户输入的编号
int number=in.nextInt();
if(number==10){


//adminStu是从Admin类中创建的对象
//调用方法create,赋值

System.out.println("请输入学生姓名:");
String name=in.next();
System.out.println("请输入学生年龄:");
int age=in.nextInt();



//stuArr是数组里面的内容 在Student类中是Java sql html c#
//添加学生
adminStu.create(name,age ,stuArr);
//更新信息
adminStu.print(stuArr);
}else if(number==11){
System.out.println("执行查找功能");
System.out.println("请输入编号");
int on=in.nextInt();
adminStu.select(on,stuArr);
}


//循环执行,把stuArr数组填满

for(int i=0;i<stuArr.length;i++){
if(stuArr[i]!=null){
System.out.println(stuArr[i]);
}
}



}
}
}


《初学Java》系列十一


第六章(七)


学生管理程序功能已经实现两个ab,接下来实现cd


c根据学生信息更新基本信息  更新就是修改的意思。
d 删除学生信息的功能


主程序5
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("---请定义学生人数---");

//为什么要定义学生人数?学生人数就是数组长度
//谁的数组?在1.0版本,数组很多,renshu是很多数组长度
//在2.0版本,直接声明一个Student的数组,用来存无数对象
//存的是用Student类创建的对象 其他对象不能进来


Student[] stuArr=new Student[in.nextInt()];

//声明一个Admin类的对象,

Admin adminStu=new Admin();

//提示产品的功能 尚未实现


//死循环
while(true){
System.out.println("你要执行的功能:");
System.out.println("10:添加一个学生");
System.out.println("11:查找一个学生:");
System.out.println("12:根据学生编号更新学生基本信息");
System.out.println("13:根据学生编号删除学生");
System.out.println("14:根据编号输入学生各门成绩");
System.out.println("15:根据某门成绩进行排序");
System.out.println("16:根据总成绩排序");
System.out.println("99:退出系统");

//判断用户输入的编号
int number=in.nextInt();
if(number==10){


//adminStu是从Admin类中创建的对象
//调用方法create,赋值

System.out.println("请输入学生姓名:");
String name=in.next();
System.out.println("请输入学生年龄:");
int age=in.nextInt();



//stuArr是数组里面的内容 在Student类中是Java sql html c#
//添加学生
adminStu.create(name,age ,stuArr);
//更新信息
adminStu.print(stuArr);
}else if(number==11){
System.out.println("执行查找功能");
System.out.println("请输入编号");
int on=in.nextInt();
adminStu.select(on,stuArr);
}else if(number==12){
System.out.println("更新学员信息");
System.out.println("请输入学员编号");
int on=in.nextInt();
System.out.println("请输入学生的姓名:");
String name=in.next();
System.out.println("请输入学生的年龄");
int age=in.nextInt();
adminStu.update(on,name,age,stuArr);

//刷新学生表 调用了print
adminStu.print(stuArr);
}else if(number==13){

//功能13,删除学生功能
System.out.println("删除功能");
System.out.println("请输入学生编号");
int on=in.nextInt();
adminStu.delete(on,stuArr);
}


//循环执行,把stuArr数组填满

for(int i=0;i<stuArr.length;i++){
if(stuArr[i]!=null){
System.out.println(stuArr[i]);
}
}



}
}
}


修改Admin类


public class Admin{
//10功能添加学生 方法如下
//方法名为creat,三个参数,传入主程序内容但是地址在Student类
// Student数组名为arr
//在Student类中new一个对象,名为stu 调用Student类中的方法
//stu调用的方法是取值set,取过来值给了对象stu
//对象stu的值存在数组Student[]中
String msg="\t编号\t姓名\t年龄\tJava\tc#\thtml\tsql\t总分\t平均分";
public void print(Student[] arr){
System.out.println(msg);
for(int i=0;i<arr.length;i++){
if(arr[i]!=null){
System.out.prinln(arr[i]);//更新信息
}
}
}
//判断学生是否存在 后面的更新功能使用
public boolean exist(int on,Student stu){
if(stu!=null){
if(stu.getOn==on){
return true;
}else{
return false;
}
}
return false;
}
public create(String name,int age,Student[] arr){
Student stu=new Student();
stu.setName(name);
stu.setAge(age);

//还没有判断是否为空 要判断一下 方法在下面

int i=this.setIndex(arr);
stu.setOn(i);


//如果Student[]数组没有空位 方法会返回99999
//没有空位的处理

if(i==99999){
System.out.println("添加满额。");
}else{
arr[i]=stu;
}


}


//判断是否数组中是否有数据 同一个对象不能添加到同一个位置


public int setIndex(Student[] arr){

//判断数组中是否有对象数据
//循环判断数组中所有位置,就是遍历

for(int i=0;i<arr.length;i++){
if(arr[i]==nall){

//为什么返回i?此下标有空位,可以放入

return i;
}
}
return 99999;
}

//实现查找学生功能的方法
//接受编号on和数组。因为从数组中找的
public void select(int on,Student[] arr){
System.out.println(msg);
for(int i=0;i<arr.length;i++ ){
if(this.exist(on,arr[i])){
System.out.prinlnt(msg);
System.out.println(arr[i]);
return;
}
}
System.out.println("查无此人");
}
//更新学生基本信息
public void update(int on,String name,int age,Student[]arr){
for(int i=0;i<arr.length;i++ ){
if(this.exist(on,arr[i])){

//修改信息

arr[i].setName(name);
arr[i].setAge(age);
System.out.println("更新成功");
return;
}
}
System.out.println("无此学生,更新失败");
}

public void delete(int on,Student[] arr){
for(int i=0;i<arr.length;i++){
if(this.exist(on,arr[i])){
arr[i]=null;//把学生信息变为零
this.print(arr);//刷新操作
return;
}
}
System.out.println("您指定的编号没有存在");
}
}


总结,每个功能处理信息的操作十分相似。首先,在主程序中写下产品的功能。次之。在Admin类文件中设置方法。
再次之,在主程序中调用该类中的方法。最后优化、运行、测试。


《初学Java》系列十二


第六章(八)


接下来实现efg功能


主程序六
import java.util.*;
public class test{
public static void main(String[]args){
Scanner in=new Scanner(System.in);
System.out.println("---请定义学生人数---");

//为什么要定义学生人数?学生人数就是数组长度
//谁的数组?在1.0版本,数组很多,renshu是很多数组长度
//在2.0版本,直接声明一个Student的数组,用来存无数对象
//存的是用Student类创建的对象 其他对象不能进来


Student[] stuArr=new Student[in.nextInt()];

//声明一个Admin类的对象,

Admin adminStu=new Admin();

//提示产品的功能 尚未实现


//死循环
while(true){
System.out.println("你要执行的功能:");
System.out.println("10:添加一个学生");
System.out.println("11:查找一个学生:");
System.out.println("12:根据学生编号更新学生基本信息");
System.out.println("13:根据学生编号删除学生");
System.out.println("14:根据编号输入学生各门成绩");
System.out.println("15:根据某门成绩进行排序");
System.out.println("16:根据总成绩排序");
System.out.println("99:退出系统");

//判断用户输入的编号
String number=in.next();
if(number.equals("10")){


//adminStu是从Admin类中创建的对象
//调用方法create,赋值

System.out.println("请输入学生姓名:");
String name=in.next();
System.out.println("请输入学生年龄:");
int age=in.nextInt();



//stuArr是数组里面的内容 在Student类中是Java sql html c#
//添加学生
adminStu.create(name,age ,stuArr);
//更新信息
adminStu.print(stuArr);
}else if(number.equals("11")){
System.out.println("执行查找功能");
System.out.println("请输入编号");
int on=in.nextInt();
adminStu.select(on,stuArr);
}else if(number.equals("12")){
System.out.println("更新学员信息");
System.out.println("请输入学员编号");
int on=in.nextInt();
System.out.println("请输入学生的姓名:");
String name=in.next();
System.out.println("请输入学生的年龄");
int age=in.nextInt();
adminStu.update(on,name,age,stuArr);

}else if(number.equals("13")){

//功能13,删除学生功能
System.out.println("删除功能");
System.out.println("请输入学生编号");
int on=in.nextInt();
adminStu.delete(on,stuArr);
}else if(number.equals("14")){
//输入成绩功能

System.out.println("执行输入成绩功能");
System.out.println("请输入学生编号");
int on=in.nextInt();
adminStu.input(on,stuArr);

}else if(number.equals("15")){
//某成绩排序

System.out.println("执行某成绩排序功能");
System.out.println("请确定课程1.Java 2.C# 3.Html 4.sql");
int on=in.nextInt();
adminStu.courseSort(sum,stuArr);
}else if(number.equals("16")){
//总分成绩排序

System.out.println("执行总成绩排序功能");
adminStu.sumSort(sum,stuArr);
}else if(number.equals("99")){
System.out.println("结束程序!");
break;
//System.exit(0)也是退出 并非跳出循环,而是彻底结束程序
}
}
}
}


修改Admin类
import java.util.*;
public class Admin{
//10功能添加学生 方法如下
//方法名为creat,三个参数,传入主程序内容但是地址在Student类
// Student数组名为arr
//在Student类中new一个对象,名为stu 调用Student类中的方法
//stu调用的方法是取值set,取过来值给了对象stu
//对象stu的值存在数组Student[]中
String msg="\t编号\t姓名\t年龄\tJava\tc#\thtml\tsql\t总分\t平均分";
public void print(Student[] arr){
System.out.println(msg);
for(int i=0;i<arr.length;i++){
if(arr[i]!=null){
arr.setSum();
arr.setAvg();
System.out.prinln(arr[i]);//更新信息
}
}
}
//判断学生是否存在 后面的更新功能使用
public boolean exist(int on,Student stu){
if(stu!=null){
if(stu.getOn==on){
return true;
}else{
return false;
}
}
return false;
}
public create(String name,int age,Student[] arr){
Student stu=new Student();
stu.setName(name);
stu.setAge(age);

//还没有判断是否为空 要判断一下 方法在下面

int i=this.setIndex(arr);
stu.setOn(i);


//如果Student[]数组没有空位 方法会返回99999
//没有空位的处理

if(i==99999){
System.out.println("添加满额。");
}else{
arr[i]=stu;
}


}


//判断是否数组中是否有数据 同一个对象不能添加到同一个位置


public int setIndex(Student[] arr){

//判断数组中是否有对象数据
//循环判断数组中所有位置,就是遍历

for(int i=0;i<arr.length;i++){
if(arr[i]==nall){

//为什么返回i?此下标有空位,可以放入

return i;
}
}
return 99999;
}

//实现查找学生功能的方法
//接受编号on和数组。因为从数组中找的
public void select(int on,Student[] arr){
System.out.println(msg);
for(int i=0;i<arr.length;i++ ){
if(this.exist(on,arr[i])){
System.out.prinlnt(msg);
System.out.println(arr[i]);
return;
}
}
System.out.println("查无此人");
}
//更新学生基本信息
public void update(int on,String name,int age,Student[]arr){
for(int i=0;i<arr.length;i++ ){
if(this.exist(on,arr[i])){

//修改信息

arr[i].setName(name);
arr[i].setAge(age);
System.out.println("更新成功");
this.print(arr);
return;
}
}
System.out.println("无此学生,更新失败");
}

//实现删除功能

public void delete(int on,Student[] arr){
for(int i=0;i<arr.length;i++){
if(this.exist(on,arr[i])){
arr[i]=null;//把学生信息变为零
this.print(arr);//刷新操作
return;
}
}
System.out.println("您指定的编号没有存在");
}

//输入成绩方法

public void input(int on,Student[] arr){
for(int i=0;i<arr.length;i++){
if(this.exist(on,arr[i])){
Scanner in=new Scanner(System.in);
System.out.println("请输入"+arr[i].getName()+"java的成绩");
arr[i].setJava(in.nextInt());
System.out.println("请输入"+arr[i].getName()+"C#的成绩");
arr[i].setC_char(in.nextInt());
System.out.println("请输入"+arr[i].getName()+"html的成绩");
arr[i].setHtlm(in.nextInt());
System.out.println("请输入"+arr[i].getName()+"sql的成绩");
arr[i].setSql(in.nextInt());
this.print(arr);//刷新操作
break;//结束功能

}
}
//根据某成绩排序功能
public void courseSort(int num,Student arr){
if(num==1){
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]!=null&&arr[j]!=null){
if(arr[i].getJava()<arr[j]get.Java()){
Student t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
}else if(num==2){
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]!=null&&arr[j]!=null){
if(arr[i].getC_char()<arr[j]get.C_char()){
Student t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
}else if(num==3){
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]!=null&&arr[j]!=null){
if(arr[i].getHtml()<arr[j]get.Html()){
Student t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
}else if(num==4){
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]!=null&&arr[j]!=null){
if(arr[i].getSql()<arr[j]get.Sql()){
Student t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
}
this.print(arr);//刷新
}


//根据总分进行排序
public void sumSort(Student[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]!=null&&arr[j]!=null{
if(arr[i].getSum<arr[j].getSum){
Student t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}

}
}
this.print(arr);//刷新
}

}


好,代码虽丑,但功能全实现。细节会错,大要不错。


《初学Java》系列十三


第六章(九)


构造代码块


public class test{
public static void main(String[]args){
//两个对象。
Person A=new Person();
Person B=new Person();
}
}


class Person{
//属性
String name;
//构造方法
//无参
Person(){
System.out.println("我是无参构造方法");
System.out.println("我在跑步");
}
//有参
Person(String name){
this.name=name;
System.out.println("我是有参构造方法");
System.out.println("我在跑步");
}
//构造代码块,大括号前面没有任何内容
//代码块前面什么也没有,主程序如何调用?根本就不必调用,而是自动运行。
//给对象初始化。构造方法与构造代码块的区别,后者是给所有对象初始化  如果存在没有赋值的对象,初始化内容就是构造代码块的内容。
//执行的时候,调用了构造方法,但是没有赋值,初始化内容就是构造代码块的内容。
//初始化,就是默认值的意思。
{
System.out.println("我是构造代码块");
//所有构造方法都有的操作
System.out.println("我在跑步");
}
}


总结,构造代码块,使用方法是{  },使用效果,根据局限条件的不同而不同。主要有两个特点,1、优先于构造方法执行。可以这样理解,{ }前面什么代码也没有,计算机的运行成本小,有限选择执行。2、和构造方法不冲突,执行完构造代码块,再构造方法。上文写了两个例子,“我在跑步”是两个构造方法皆具备,于是在{ }处理,二者可以省去这代码。


构造函数之间的调用


public class test{
public static void main(String[]args){
Student S=new Student("似花非花人",21);
}
}


class Student{
String name;
int age;
Student(String name){
this.name=name;
}
Student(String name, int age){
this.name=name;
this.age=age;
}
}
构造函数就是构造方法的意思。构造函数之间的调用有两个要点。1、必须用this语句完成。比如this(name),其中name是方法名。2、调用其他构造方法,一定要放在首句。原因不详。就是这样规定的。不然会报错。


static 关键字详解


public class test{
public static void main(String[]args){
Student a=new Student();
a.country="China"
Student b=new Student();
System.out.println(b.country);
}
}


class Student{
String name;
int age;
static String country
}


1.static是修饰符。静态的意思。怎么理解在这里的作用呢?我们可以举个例子,成立一个公司,要给公司起名字,比如“似花xx有限责任公司。”只要是和这个公司有业务往来的人,都可以称呼“似花公司”,谁都可以叫,公司内部员工也是可以教的,我们就用static把公司名字取出来,它就是静态变量。如果公司内部改名了,那么就不能再用了。


这样理解,可能会误导,我们还可以画一张内存图。
“栈区:”
“堆区:”
“数据区(方法区、共享区)”
用内存图解释上述代码,我们用Student new一个对象,这个对象的属性,name age country 在堆区,对象名(成员名)在栈区。所有new的对象的country都是Chian,既然如此。我们就把country这个属性拿出来,放到数据区。怎么拿出来?用static拿,static country 这样,同Student new 出来的对象都能访问、调用它。
“栈区:abcedfghi.....”
“堆区:[] [] []......”
“数据区(方法区、共享区):static country ”


2.类也可以调用。比如Student.country
优先于对象而存在。(感觉属性都是优先存在的)
静态变量(类变量)static String country
实例变量,int age(存在于堆区)
类变量存在于data内存区(数据区、方法区、共享区)


生命周期
1.静态变量(类变量)类存我存。类亡我亡。
2.实例变量(int age),随对象而存亡。


public class test{
public static void main(String[]args){
Student a=new Student();
a.country="China"
Student b=new Student();
System.out.println(b.country);
}
}


class Student{
String name;
int age;
static String country

//用static修饰的方法
static void print(){
System.out.println(country);
}
}


静态方法只能访问静态成员,因为要防止一种现象,主程序中访问了这方法,但是没有new对象。效果只能是无从访问。但是静态成员优先于对象存在,所以说,没有对象也是存在的,静态成员和静态方法同时存在的。能够访问。


注意区分成员和局部变量。局部变量是不能被static修饰的。只能修饰成员变量和方法。


静态方法不能修饰this和super 因为静态的优先级对象存在,所以静态方法不可以出现this


总结


1.static是修饰词,只能用来修饰成员变量和成员方法。


2.被static修饰的成员变量只能一份


3.静态变量可以被类调用


4.随着类的加载而被加载


5.优先于对象存在


6.存放于data区(数据区、方法区、共享区)


7.非静态的方法既能访问静态成员,又能访问非静态成员


8.静态方法不能定义this和super关键字 (因为this指对象,如果主程序中没有new对象,这边就如从访问 )


有一个很明显的特点就是数据共享。一个对象使用,不影响其他对象的使用,这样给出一个地址便是了。好处就是减少了 对象的代码,降低了程序员的机会成本。时间就是成本。可以想象,面对很多对象的相同属性内容,一个是写无数个代码,一个是写个static。很明显,后者用的时间少。时间多的就是时间少的成本,二者相互间是机会成本。机会成本是指放弃的最高收入。




《初学Java》系列十四


第六章(十)


main方法
主函数就是主方法的意思。
public class test{
public static void main(String[] args){

}
}
这个从第一节课就开始敲的代码,现在突然知道了其中含义,惊讶的手足无措。
这就是一个类。多了一个public而已。我们去掉public
class test{
public static void main(String[] args){

}
}
就是一个类了 然后static是修饰词,静态变量。void是无返回,(String[] args)是参数。String[]是一个数组。main是函数名


public class test{
public static void main(String[] args){

}
         //在cmd中也能赋值 还不用写Scanner
}


总结
1.public(访问修饰符,公共的)代表该类或者该函数访问权限是最大的
2.static 代表主函数随着类的加载便已经存在
3.void 代表主函数随着类的加载就已经存在
4.main main不是关键字,能够被JVM识别的单词
5.String[] args 函数的参数,参数类型是String数组。接受字符串


静态工具类


求最大值的ArrayOperate类
public class ArrayOperate{
//重点是看到了static的使用。
public static int max(int[] arr){
int max=arr[0];
for(int i=0;i<arr.length;i++){
if(max=arr[0]){
max=arr[i];
}
}
}
}


对象是用来封装专用数值的。只要不是专用的,就放到类里了。


classpath


是寻找class文件的意思。在环境变量中设置一个地址就可以了。变量值是地址。
比如“.;E\;”.是当前的意思。分号是隔开。这些百度都可以查到。没有讲解必要。


Java文档注释


方便别人使用。或是方便客户使用。这个是文档说明。就是平常使用的注释。其中用到一些符号,@param arr,这个文档的标识符。@return,@是文档标识符的意思。
文档提取
Javadoc -d Mydoc  -author ArrayOperate
文档       文档名


JavaAPI
百度


静态代码块
static{
静态代码块中执行语句
}
特点:随着类的加载而执行。并且只会执行一次。并且还优先于主函数
作用:用于给类进行初始化


一个是静态,一个是构造代码块


class Person{
public static void main(String[] args){
System.out.println("我是主函数");
}
static{
System.out.println("我是静态代码块");
}
{
System.out.println("我是构造代码块" );
}
}


调用检验
class test{
public static void main(String[] args){
new Person();
new Person();//匿名对象
}
}
显示的结果,出现两次我是构造代码块,一次我是静态代码块  因为后者只能运行一次


下面详细讲解内存调用过程
class Student{
static{
System.out.println("我是静态代码块");
}
{
System.out.println("我是构造代码块" );
}
void print(){
System.out.println("我是普通方法");
}
private String name="ff";//显示初始化
private static country;
}


public class test{
public static void main(String[] args){
Student s=new Student();
}
}


静态成员 静态代码块 对象各自的位置  堆区 栈区 数据区


new Student() 这个是new对象的过程,要调用Student类。先要调用Student类。cpu把Student类加载进入内存
当Student类加载进入内存,谁随着类的加载而被加载?当然是静态成员,谁随着类的加载而被执行?静态代码块 于是这两者都进入了内存→方法区


方法区: country   void print(){ 普通方法的调用要通过new对象  }


堆区: 对象(内存地址)(特有属性 name 默认为null)


栈区:s(对象的内存地址)


我的问题是类放在哪里?类的方法放在方法区啊。那么赋值的“ff”放在哪里是不是不重要?假设是不重要的。看看后面有什么影响。如果走投无路,那就是重要的。
总结
1.因为new Student()用到了Student类,所以会把它从硬盘上加载进入内存
2.如果有static静态代码块就会随着类的加载而执行
静态成员和普通方法也会随着类的加载而执行
3.在堆中开辟空间,分配内存地址
4.在堆中建立对象特有属性,并同时对特有属性进行默认初始化
5.对属性惊醒显示初始化
6.执行构造代码块,对所有对象进行初始化
7.执行对应的构造函数,对对象进行初始化
8.讲内存地址给s(给栈中的变量)


单例设计模式


前人栽树后人乘凉。java有23中设计模式。针对一类问题最有效的解决方式。代码是记不住的。模式是一种思想。这令我想到周以真的计算机思维。在《Java语言程序设计》提到过,我专门查了她的论文。但是没有看懂。提到术语众多,看不懂。
单例设计模式:解决一个类只在内存中存在一个对象
如何让一个类在内存中只存在一个对象?
1.禁止其他的应用程序。通过此类来创建对象。
2.既然外部不能通过此类创建对象了,我们要用对象,就可以在本类里面创建本类对象
3.为了其他应用程序能够访问到本类里面创建的对象,我需要对外界提供一种访问方式。
如何实现?
1.私有化构造方法
2.在本类中创建本类对象
3.对外界提供访问方法


class Person{
String name;
private Perdon();
static Person p=new Perdon();
public static Person getInstance(){
`}
}


public class test{
public static void main(String[]args){
Person A=Person.getIntstance();
A.name="似花非花人";
Person B=Person.getInstance();
System.out.println(B.name);
}
}


代码简单,解读越发诡异,要用内存过程解读。


堆区,栈区,方法区 上文的分析再来一遍。


方法区: static Person  { 普通方法的调用要通过new对象  }


堆区: 对象(内存地址)(特有属性 name 默认为null)


栈区:A B(对象的内存地址)


继承


class Student{
String name;
int age;
void study(){
System.out.println("学习");
}
}


class Teacher{
String name;
int age;
void teach(){
System.out.println("教书");
}
}
这两个类有共同内容
String name;
int age;
我们可以抽取
class Person{
String name;
int age;
}
然后在student和teacher 中的内容省略
class Student  extends Person{

void study(){
System.out.println("学习");
}
}


class Teacher extends Person{

void teach(){
System.out.println("教书");
}
}
此时他们的关系,
Person称之为父类、超类、基类
Student和Teacher成为子类 extends是关键字


效果,1.提供了代码复用性。
2.让类与类之间有了继承关系,为的是后面的多态特性的存在
3.猫类和小猫咪才有继承关系。如果是猫类里面就不能有狗的对象,就不要建立继承关系。
感觉就是一个必要非充分的关系,再讲一个例子。
“哺乳动物 哺乳”
“猫科  吃.....”
“猫 捕鼠......”、“豹子 奔跑.....”


如何表述这种关系?很明显,用继承描述
class Mammal{
String buru="哺乳";
}
class MaoKe extends Mammal{
private String color;
void eat(){
System.out.println("吃");
}
}
class Cat extends MaoKe{
void CatchMouse(){
System.out.println("捕鼠");
}
}
class Leopard extends MaoKe{
void LeochMouse(){
System.out.println("奔跑");
}
}
总结
1.子类拥有父类的成员,子类不能拥有父类中被private修饰的成员
2.java多层继承,在多层继承中,最下层的子类拥有整个继承体系的成员
最上层的父类里面定义所有子类的共性描述。
3.Java中不支持多继承。Java设置了多实现,通过接口实现这种功能。一个类有其他几个类的功能,可以通过接口来实现。


配上之前学过的一张图,好教我等知道学到了哪个方面。


《初学Java》系列十五


第六章(十一)


小结


在系列十四,给了一张图,现在解释一下这张图什么意思。我们要知道Javase里面有哪些内容,就需要这张图的指引。


基础程序设计→Java新特性→面向对象程序设计→eclipse→应用程序开发


基础程序设计是一个大盒子,里面有它的一些概念,比如数据类型,控制语句,数组和方法。我们还可以把数据类型看成一个小盒子,里面放着int、double、boolean、引用类型。还可以往里面再放内容,比如怎么使用int,怎么使用double,他们的默认值是怎样的,怎么给他们赋值等等。


Java新特性,里面有泛型、枚举、装箱拆箱、可变参数等


面向对象程序设计,封装,继承,多态,设计模式,异常,包


eclipse,有jdt、junit、cvs等


应用程序开发,有类集,二叉树,链表,类库,多线程,io,反射,网络,jdbc
(连接Orade,数据库)


我现在所处的位置是面向对象程序设计中的多态和异常。甚至没有用到eclipse,写代码用的是记事本。知道这个有什么用?我之前说Java是迷雾森林,现在找到了地图,知道自己存在的位置,这就是图的作用。


好,继续本次内容


子父类中的成员变量


//父类
class Person{
String name="似花";
}


//子类
class Student extends Person{
String name="非花";
void show(){
System.out.println(name);
}
}


//主程序
public class test{
public static void main(String[] args){
stu.show();
}
}
现在的问题是,如果输出,会出现什么结果?会出现非花,以为这是一个局部变量,name的意思是this.name,当前的类给的数值。this访问的是子类的成员。
super修饰词的作用


class Student extends Person{
String name="非花";
void show(){
System.out.println(super.name);
}
}//super意思是超,这是就是超越本类的内容,直接访问父类内容。输出结果是似花。


好,我们复习之前学过的this的知识。系列五提到:
【this.name=name;//把name赋值给了this.name
this.age=age;//把aga赋值给了this.aga
this.color=color;//把color赋值给了this.color
(1、this代表使用该方法的引用,什么意思呢?现在one在使用这个堆区的对象。this对应one。它的意思就是one的意思。如果是two,this就对应这two,这是实参传入的对象就是two的。
2、this.name 指调用了成员属性String name,然后把name赋值给它,这个name是实参传过来的数据)】


再次总结
this 代表当前对象的引用,this.变量 首先在本类中找需要的这个变量如果没有就去父类中找
super 用于访问当前对象的父类成员 super.变量 指直接在父类中找所需变量。
如果父类中没有相关数据,程序报错。


子父类之函数覆盖(重写)


class Animal{
String Type;
void run(){
System.out.println("跑步中");
}
}


class Cat extends Animal{


}
class Dog extends Animal{


}


public class test{
public static void main(String[] args){
Cat C=new Cat();
C.run();
Dog d=new Dog;
d.run();
}
}//子类调用了父类方法。输出的是父类run内容。这个是继承,没有问题。


现在改变子类方法,主程序中输出的结果为什么变化?
class Dog extends Animal{
public void run(){
Type="哮天犬";
System.out.println("唱着歌跑步中");
}
}//子类方法和父类方法一样了。此时输出的结果是“唱着歌跑步中”
函数名一样,怎么解释?(函数名就是方法名。函数贴近术语。)


总结


1.当子类中出现和父类中一样的函数时,当子类对象调用该函数,运行的是子类的函数。父类函数被覆盖,这是函数特性:重写。


2.子类覆盖父类时,必须保证子类权限大于等于父类。这个是充分天条件,不可缺少。


3.访问权限修饰符:public >default >private 成员前面没加任何访问修饰符,默认访问权限是default
在父类中是public void run
子类中也要public void run 这个就是访问权限相等或等于的时候,子类方法才能使用。


4.重载只看重名的参数列表。


5.静态的函数只能覆盖静态函数。


6.子父类函数要一模一样才能一样。public void run 和 public void run


内存图解释
“栈:C、D(调用函数)”
“方法区:animal (run) Cat() Dog(run)”
找到了子类中的函数,便输出了,因为是重写和覆盖,所以是先有的父类,因为父类在对象new出前就存在,所以是覆盖了


继承中的构造函数
extends继承


构造函数复习一下


【 在系列五中  //1、有无构造方法效果对比。2、构造方法和普通方法效果对比。
class Cat{
String name;
int age;
//第一个构造方法,里面为null 构造方法与类同名。Cat
Cat(){

}
//第二个构造方法。
Cat(String name,int age){
this.name=name;
this.age=age;
System.out.println("姓名"+this.name+"年龄"+this.age);
}
//普通方法。用来对比。因为有void
void get(){
System.out.println(this.name);
}
}
public class test{
public static void main(String[]args){
Cat one=new Cat("似花非花人",100);//构造方法用来初始化
one.get();
Cat two=new Cat("hah",13);
two.get();
}
}//构造方法是用来初始化的。
最简单的构造方法用之创建对象Cat one=new Cat()】


现在加上继承的局限
class fu{
String name;
fu(){
System.out.println("父类中的构造函数");
}
}
class zi extends{
zi(){
System.out.println("子类中的构造函数");
}
}


public class test{
public static void main(String[] args){
zi z=new zi();
}
}


输出结果是:
父类构造函数
子类构造函数
为什么是两条语句?因为子类构造函数中,第一条默认super()
super是超啊


总结
1.在对子类对象进行初始化时,父类构造函数会运行。
2.子类每个构造方法都有一个隐式super


如果加进去有参的情况呢?父类子类调用又将如何?
class fu{
String name;
fu(){
System.out.println("父类中的构造函数");
}
//方法重载
fu(String n){
System.out.println("父类有参构造函数");
}
}
class zi extends{
zi(){

System.out.println("子类中的构造函数");
}
zi(String n){
super("haha");
this.name="hahahhaha";
System.out.println("子类构造方法");
}
}


public class test{
public static void main(String[] args){
//赋值给参数
zi z=new zi("似花");
}
}
输出结果:
父类有参构造函数
子类构造函数。


因为加了参数super("hahah"),调用了父类中的有参构造方法。


对象转型


class Animal{
void sleep(){
System.out.println("睡觉中");
}
}
class Cat extends Animal{
void catchMouse(){
System.out.println("捕鼠");
}
}
class Dog extends Animal{

}


public class test{
public static void main(String[] args){
Animal a=new Cat();//向上转型
Cat c=(Cat)a;//类似数据类型的转换。向下转型。
a.catMouse;
a.sleep();

}
}
总结
1.向上转换,默认
2.向下转型,强制。(b=(Cat)a)


关键字instanceof的用法,测试左边的对象是否为右边类的实例,如果是,返回true,不是返回false
比如Cat a=new Cat();
    System.out.println(a instanceof Dog);//左边为a猫,右边为Dog类,不是它的实例,返回false,报错。


多态


事物存在的多种形态。比如动物:猫狗等等。人:婴儿,儿童,青少年,青年人,
class Animal{
void sing(){
System.out.println("唱歌");
}
}
class Dog extends Animal{
void sing(){
System.out.println("汪汪的唱歌");
}
}
class Cat extends Animal{
void sing(){
System.out.println("喵喵的唱歌");
}
void catchMouse(){
System.out.println("捕鼠")
}
}
public class test{
public static void main(String[] args){
Cat c=new Cat();
c.sing();
Cat c1=new Cat();
c1.sing();
Cat c2=new Cat();
c2.sing();//代码重复
}
public static void function(Cat c){
c.sing();
}
}//
修改1
public class test{
public static void main(String[] args){
Cat c=new Cat();
Cat c1=new Cat();
Cat c2=new Cat();
function(c);
function(c1);
function(c2);
}
public static void function(Cat c){
c.sing();
}
}//
修改2
public class test{
public static void main(String[] args){
Cat c=new Cat();
Cat c1=new Cat();
Cat c2=new Cat();
function(c);
function(c1);
function(c2);
Dog d=new Dog();
function(d);
}
public static void function(Cat c){
c.sing();
}
public static void function(Dog c){
d.sing();
}
}//
修改3
public class test{
public static void main(String[] args){
Cat c=new Cat();
function(c);

Dog d=new Dog();
function(d);
}
public static void function(Animal c){
c.sing();
}
}//
多态的体现 父类引用指向子类对象,
多态的前提,
1.必须是类与类之间的存在关系,可以是继承,也可以是实现关系


2.必须得有重写。


多态成员变量的特点
1.参阅的是引用型变量所属的类中是否有调用的方法
2.运行,参阅对象所属的类中是否有调用的方法


《初学Java》系列十六


第六章(十二)


多态练习


import java.util.*;
class FK{
void bx(){
System.out.println("变形");
}
}
class FK_szx{
void bx(){
System.out.println("山字形变形");
}
}
class FK_lzx{
void bx(){
System.out.println("L字形变形");
}
}
class FK_zzx{
void bx(){
System.out.println("L字形变形");
}
}
class FK_cfx{
void bx(){
System.out.println("L字形变形");
}
}
class test{
public static void main(String[] args){
Random r=new Random();
int a=r.nextInt(3);
switch(a){
case0;
FK_szx szx=new FK_szx();
szx.bx();
break;


case1;
FK_lzx Lzx=new FK_lzx();
lzx.bx();
break;


case2;
FK_zzx zzx=new FK_zzx();
zzx.bx();
break;


case3;
FK_cfx cfx=new FK_cfx();
cfx.bx();
break;
}
}
}
优化


class test{
public static void main(String[] args){
Random r=new Random();
int a=r.nextInt(3);
FK fk=null;
switch(a){
case0:
fk=new FK_szx();
break;


case1:
fk=new FK_lzx();
break;


case2:
fk=new FK_zzx();
break;


case3:
fk=new FK_cfx();
break;
}
fk.bx();
}
}


匿名对象
1.没有名字的对象
2.当对对象的方法只调用一次时,我们可以用匿名对象来完成
3.匿名对象可以被当成实参传递。
class Car{
String color;
void start(){
System.out.println("汽车被开动");
}
}
主程序1
public class test{
public static void main(String[] args){
new Car().start();

}
}


主程序2
public class test{
public static void main(String[] args){

print(new Car());//当成了形参
}
static void print(Car c){
c.start();
}
}


Object
在Java.lang包中


1.它是所有对象的直接或间接父类,根父类,它里面定义的功能是所有对象都应该具备的。
2.定义新类当没有指明继承。默认继承Object




class Animal{


}
class Cat{


}
class test{
public static void main(String[] args){
Cat c=new Cat();
System.out.println(c.toString);//这便是默认的Object类中的toString函数
}
}
再看
class Animal{


}
class Cat extends Animal{//继承了。但是Animal没有继承,默认继承Object类


}


默认父类
class Object{
public String toString(){

}
}


不满意默认的Object,在子类中修改函数
class Cat extends Animal{
public String toString(){
return "ff";
}
}


Object类之equals
在API中有其介绍
class Cat{
int num;
public boolean ff(Cat c){
return this.num==c.num;
}


}
public class test{
public static void main(String[] args){
Cat c=new Cat();
Cat c1=new Cat();
c.ff();//意思是把c这个参数传给了Cat类中的this
}
}
==和
Object里面的equals比较的是两个对象的内存地址。
class Cat{
int num;
public boolean ff(Cat fff){
return this.num==fff.num;
}


}
public class test{
public static void main(String[] args){
Cat c=new Cat();
Cat c1=new Cat();
System.out.println(c.ff(c2));
}
}
修改
class Cat{
int num;
public boolean ff(Object fff){//Object可以接受如何类型的数值
return this.num==fff.num;
}


}
class Dog{

}
public class test{
public static void main(String[] args){
Cat c=new Cat();
Dog c1=new Dog();
System.out.println(c.ff(c2));
}
}


再修改
class Cat{
int num;
public boolean equals(Object fff){//方法重写
if(fff instanceof Cat){//instanceof关键字
Cat.ee=(Cat)fff;//向下转换。Object→Cat
return this.num==ee.num;//
}else{
return false;
}
}
}


final
1.修饰类 函数 变量
2.被修饰的类不能被其他类继承。
3.被修饰的函数不能被重写
4.被修饰的变量不能再赋值 应在修饰时赋值。
5.被final修饰的变量称之为常量。不能被改变 常量命名规范,字母全部大写
class Person{
void show{
System.out.println("你好");
}
}
class Student extends Person{

}
public class test{
public void main(String[] args){
Student s=new Student();
s.show();
}
}
加final
final class Person{
void show{
System.out.println("你好");
}
}
class Student extends Person{

}
public class test{
public void main(String[] args){
Student s=new Student();
s.show();
}
}//结果报错,因为final修饰的类不能被继承


在方法中添加final
class Person{
final void show{
System.out.println("你好");
}
}
class Student extends Person{

}
public class test{
public void main(String[] args){
Student s=new Student();
s.show();
}
}//方法不能别调用。


加final的方法不能被重写、不能再次赋值
final String name="方法";
final int a=3.14;


final static String STUDENT_NAME//全局常量


抽象类
abstract class Animal{
abstract void sing()//抽象的函数
}
class Cat extends Animal{
void sing(){
System.out.println("喵喵");
}
}
class Dog extends Animal{
void sing(){
System.out.println("汪汪");
}
}
public class test{
public static void main(String[] args){
Cat a=new Cat();
a.sing();
}
}
总结
1.是一个修饰符,方法、类
2.函数抽象,类也是要抽象的。这个是充分关系。但是抽象类中不必都是抽象函数。
3.使用条件,当我们多个类存在相同功能时,功能主体却不同时。向上抽取。只抽取功能定义,不抽取功能主体。
4.抽象中的类不能创建对象。
5.抽象类的函数调用,子类先继承抽象类,再重写抽象类中函数,并创建子类对象来调用。
6.抽象类中可以定义非抽象函数。
7.抽象类不能new对象。但是子类函数第一行默认super,会在子类中new对象。
8.如果子类只重写抽象类中一部分函数,报错,不通过。必须重写抽象类所有方法。


比如
abstract class Animal{
abstract void sing()//抽象的函数
}
class Cat extends Animal{
void sing(){
System.out.println("喵喵");
}
}
class Dog extends Animal{
void sing(){
System.out.println("汪汪");
}
}
public class test{
public static void main(String[] args){
Animal a=new Cat();
a.sing();
}
}


模板设计模式
先写一段代码
求一段代码运行时间
class Demo{
public void getTime(){
long start =System.currentTimeMillis();
for(int i=0;i<10000;i++){
System.out.println("ff");
}
long stop=System.currentTimeMillis;
System.out.println("共耗费:"+(stop-start));
}
}
pubic class test{
public static void main(String[] args){
Demo d=new Demo();
d.getTime();
}
}//把这个计算方法一般化,计算更多。


修改
class Demo{
public void getTime(){
long start =System.currentTimeMillis();
function();
for(int i=0;i<10000;i++){
System.out.println("ff");
}
public void function(){
for(int i=0;i<10000;i++){
System.out.println("ff");
}
}
long stop=System.currentTimeMillis;
System.out.println("共耗费:"+(stop-start));
}
}
//把Demo放到了子类test1中。在主程序中直接调用了。
class test1 extends Demo{
public void function(){
System.out.println("方法");
}
}
pubic class test{
public static void main(String[] args){
Test d=new Test();
d.getTime();
}
}
优化 用到abstract抽象类 final、覆盖也用到了。
abstract class Demo{
public final void getTime(){
long start =System.currentTimeMillis();
function();
long stop=System.currentTimeMillis;
System.out.println("共耗费:"+(stop-start));
}
public abstract void function();
}
class test1 extends Demo{
public void function(){
for(int i=0;i<1000;i++){}
System.out.println("方法");
}
}
pubic class test{
public static void main(String[] args){
Test d=new Test();
d.getTime();
}
}
总结


模板设计模式:功能一部分已知,还有要变化的未知的部分。我们在父类中确定已知功能,在子类中完成需要改变的内容。


模板可能就是模具理论。


《初学Java》系列十七(完结篇)


第六章(十三)


接口


接口是一个特殊的抽象类,当抽象类中全部是抽象方法时,可以通过接口的形式来体现。
class用于定义类
interface用于定义接口
接口成员的格式:
1.public static final String NAME="小李";//全局常量
2.public abstract void show();//抽象方法
3.接口中只能出现public访问修饰符(不能出现private)
4.接口不可以创建对象。因为里面有抽象方法,需要被子类实现,子类对接口中的所有抽象方法实现后,子类才能够实例化。否则子类就是一个抽象类


系统默认形式
interface smoket{
public static finnal String NAME="小李";
public void show();
}
public class test{
public static void main(String[] args){

}
}
既然是默认,可以省略
interface smoket{
String NAME="小李";
void show();
}
public class test{
public static void main(String[] args){

}
}


例子:
interface smoket{
public static finnal String NAME="小李";
public  abstract void show();
}
class Student implements smoket{//关键字,是实现接口的意思
public void show(){
System.out.println("在吸烟");
}
}
public class test{
public static void main(String[] args){
Student s=new Student();
s.show();
}
}


接口二
Java不支持多继承,因为存在安全隐患,当父类中定义了相同功能,功能不能时,子类不确定运行哪个。于是出现了多实现。只有类与接口之间才有多实现。


关系:
类与类之间,继承关系 extends
接口与类之间,实现关系。 implements
接口与接口之间,继承关系。extends




interface Smoker{
public abstract void smoket();
}
//接口中没有方法主体。
interface Game extends Smoket{
public abstract void computerGame();//默认的抽象方法。调用的时候,是调用抽象方法
}
class Student implemer Smoket,Game{
public abstract void smoket(){ //方法名要一样才行。
System.out.println("吸烟");
}
public void computerGame(){
System.out.println("游戏");
}
}
public class test{
public static void main(String[] args){
Student s=new Student();
s.smoket();
s.computerGame();
}
}
接口三
1.降低了事物与事物之间的耦合性(关系紧密程度)
比如开发,没有接口,这边不能完成,那边不能开始。有了接口,就可以同时开始,然后连接。提高了工作效率。我们可以用模具的思想去理解。
2.父类中定义的是基本功能。(即多个类中皆有的功能) 接口中定义的是拓展功能。
3.接口能够多实现。一个类可以实现多个接口。


class  Person{
String name;
int age;
}
interface Smoke{
public abstract void smoke();
}
class Student extends Person{

}
class Worker extends Person implements Smoke{//继承Person implements实现关系,可以不实现的。所以是降低了事物之间的耦合性。
public void smoke(){
System.out.print("在抽烟");
}


}


public class test{
public static void main(String[] args){
Worker s= new Worker();
s.smoke();
}
}


包(package)
类似文件夹。管理的内容是类。
1.对类进行分类管理
2.给类提供了多层命名空间
3.定义了包的类,类名全称包名.类名 字母全部小写。package pack;
4.定义语句必须在第一行。


package pack;
public class test{
public static void main(String[] args){
System.out.println("hellow java!");
}
}
包与包之间的访问权限
package a.b.c;//为了使包名具有唯一性,通常用url做包名 a.b.c.意思是,a包中的b包中的c包。
class test{
public static void main(String[] args){

}
}
访问权限修饰符,
       public protected default private
同一个类 ok    ok    ok   ok
同一个包 ok    ok    ok
子类 ok    ok
不同包 ok
类只能被public和default访问权限修饰符修饰。
当一个记事本中定义了多个类,只能出现一个public的类
类中的成员可以被以上四种访问权限修饰符修饰。


jar包
对包(文件夹)的操作。
在cmd命令窗口操作。
包压缩成jar包,原来的包就没有了。
jar包→包→类


调用的时候
1.在cmd中改变路径
set classpath=E:\tongji\Tool.jar【有些是包名】


set classpath=.;E\tongji\Tool.jar【.是当前目录的意思。;是分隔符】


JDK提供了自己的jar包。JDK\bin目录中
com.sun.tools.javac.Main意思是com包中的sun包中的tools包中的javac包中的Main类。
com→sun→tool→java→Main


举例,import java.util.Scanner 导入util包中的Scanner类。
在JDK\JRE\LIB\RT\JAVA\UTIL\SCANNER这个目录下。




导入包import
package stu;
class Student{
void show(){

}
}


package demo;
class test2{


}
package aa;
class test1{


}
主程序
import stu.*;//*是通配符,导入所有类
import demo.*;
public class test11{
public static void main(String[] args){
Student s=new Student();
}
}


初级阶段的Java学习结束。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页