J面向对象程序设计第三次博客
面向对象程序设计第三次博客
一:前言
(1):知识点
JavaFX的安装与基本使用
抽象类的作用以及使用
容器ArrayList的增删改查
迭代器的查找
(1):JavaFX的安装与基本使用
一:概况
窗口(stage):窗口里面可以设置场景,但是一次只能显示一个场景。
场景(scene):场景可以添加UI组件图的树形结构。
根节点(parent):根节点设置为一个布局,放置不同的节点(组件)。可以在根节点嵌套放置根节点。
二:基本类
On Drag Detected:当你从一个Node上进行拖动的时候,会检测到拖动操作,将会执行这个EventHandler。
On Drag Done:当你拖动并松手的时候,执行Drag完成操作。
On Drag Dropped:当你拖动到目标并松开鼠标的时候,执行这个DragDropped事件。
On Drag Entered:当你拖动到目标控件的时候,会执行这个事件回调。
On Drag Exited:当你拖动移出目标控件的时候,执行这个操作。
On Drag Over: 当某被拖动的对象在另一对象容器范围内拖动时触发此事件,会不停的执行。
On Mouse Drag Entered:定义当完全按下并释放手势进入节点Node时要触发的事件。
On Mouse Drag Exited:定义当完全按下并释放手势离开节点Node时要触发的事件。
On Mouse Drag Over:定义在节点Node中完全按下并释放手势时要触发的事件。
On Mouse Drag Released:定义在节点Node中完全按下并释放的手势(通过释放鼠标按钮)结束时要触发的事件。
On Key Pressed:当键盘按键被按下的时候触发事件。
On Key Released:当键盘按键按下后被释放的时候触发事件。
On Key Typed:只会响应文字输入键,如字母、数字和标点符号等,它不会响应CTRL/ENTER/F1等功能键。
参考文献:
(1条消息) JavaFX之Scene Builder详细使用说明之设置篇(4)——代码Code_二木成林的博客-CSDN博客
(2)抽象类的作用以及使用
一:抽象类的作用
1、在面向对象方法中,抽象类主要用来进行类型隐藏。构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组
任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的。
2、通过从这个抽象体派生,也可扩展此模块的行为功能。为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。
3、抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
通常在编程语句中用 abstract 修饰的类是抽象类。在C++中,含有纯虚拟函数的类称为抽象类,它不能生成对象;在java中,含有抽象方法的类称为抽象类,同样不能生成对象。
抽象类是不完整的,它只能用作基类。在面向对象方法中,抽象类主要用来进行类型隐藏和充当全局变量的角色。
抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。
抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象
二:抽象类的使用
1.抽象类和抽象方法的格式
抽象的关键字是abstract
抽象类: 加上abstract关键字修饰
抽象方法: 加上abstract关键字修饰,去掉大括号
2.抽象类和抽象方法的使用
要想使用抽象类和抽象方法必须具备继承关系
3.抽象类的注意事项
1.抽象类可以具有所有普通类具拥有的东西
2.抽象方法没有大括号
3.抽象类不能创建对象
4.抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
5.抽象类的子类必须重写父类的所有的抽象方法(子类是抽象类除外)
6.抽象类的构造方法是提供给子类初始化父类成员使用的
参考文献
(1条消息) Java 抽象类的使用介绍_二师兄想吃肉的博客-CSDN博客_java抽象类的使用
三:容器ArrayLIst的增删改查
ArrayList不是多线程版本的容器,因此不需要做同步操作synchronized,保证了操作的效率,如果我们需要对单个ArrayList容器做多线程操作,可以在外部进行同步控制。而List家族
另一个古老的容器类Vector则是多线程版本的,现在使用不多。
1.增
①add()方法在数组实际存储的最后一个元素后面添加一个元素
②add(int, E) 在指定位置放上一个元素。
③addAll(Collection<>) 将给定容器中的所有元素都加入到本容器的尾部
2.删
①remove(int) 删除指定位置上的元素。
②remove(Object) 删除容器数组中的一个具体元素,该元素equals传入的参数,只删除第一次出现位置上的元素。
③removeAll(Collection<>) 从本容器中批量删除与给定容器中所有元素相同的元素。
④removeIf(Predicate<>, int, int) 给定一个检测器Predicate,从本容器数组的i位置开始查找,一直到end为止,如果满足条件,则删除该位置上的元素。
3.改
①set(int, E)方法将给定索引位置上的元素值修改为其他元素值,最后返回索引位置的旧值。
4.查
①get(int) 获取到给定索引位置的元素。
②indexOf(Object) 方法获取容器数组中,与给定元素相等的第一个元素所在的索引位置。
四:迭代器的使用
迭代器 it 的两个基本操作是 next 、hasNext 和 remove。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
删除元素
要删除集合中的元素可以使用 remove() 方法。
参考文献
(1条消息) JDK源码阅读(六) : 容器——ArrayList_リュウセイリョウ的博客-CSDN博客
二:设计与分析
一:电信计费
(1):座机用户打电话
获取用户通话电话号码以及打电话人所在区域,接电话人所在区域,通话时长,针对不同区域进行不同计费类型,最后输出打电话费用以及剩余电话费用。
(2):手机与座机同时计费
要获取是手机还是座机,如果是手机还得单独获取手机所在区域,手机增加了一个计费类型,就是当手机在省外区域时,需要考虑漫游计费;
(3):短信计费
短信来说,就不需要考虑出现的位置,只需要考虑信息长度,整个代码思路还是清晰的;
(4):设计
电话号码的获取,最开始以为输入的电话号码位数是固定的,直接采用CharAt获取后面的字符串,但是最后才意识到不对,之后是采用spilt分割,将数组第一位处理,储存在电话号码
中,如果是座机,第二位便是接电话,如果不是,判断数组长度,如果是六位,那就是都是座机,如果是七位,就是一个座机一个手机,如果是八位,那就是两个都是手机,所以数据处理
起来还是很好的。
时间的获取以及输入时间段的格式是否正确,采用simpledataformate,这个可以判断时间格式是否正确,还能够获取时间长度
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args)
{
// Scanner input = new Scanner(System.in);
// String str = input.nextLine();
String[] ss = new String[20];
getinput in = new getinput();
ss = in.getit();
people[] p = new people[20];
people[] pc = new people[20];
people[] pa = new people[20];
people pp = new people(" ");
pp.getpeople(p, ss);
pc = pp.getcallpeople(ss);
pa = pp.getanswerpeople(ss);
pp.dealmeassage(pc);
pp.dealmeassage(pa);
pp.getcallmoney(pc);
pp.getanswermoney(pa);
p = pp.getrealpeople(p, pc, pa);
in.output(p);
// input.close();
}
}
//获取输入并处理
class getinput
{
public String[] getit()
{
Scanner input = new Scanner(System.in);
String[] ss = new String[20];
sum a = new sum();
int i;
i = 0;
boolean flag;
while(true)
{
String line = input.nextLine();
ss[i] = line;
if(ss[i].equals("end"))
break;
flag = a.isright(line);
if(flag)
{
ss[i] = line;
i++;
}
}
a.cutit(ss);
return ss;
}
//输出
public void output(people[] pp)
{
int i,j,m,n,f;
people p = new people();
// for(i=0;i<pp.length&&!(pp[i]==null);i++)
// {
// for(j = i;j<pp.length&&!(pp[j]==null);i++) {
// if()
// }
// }
for(i = 0;i<pp.length&&!(pp[i]==null);i++)
{
System.out.printf(pp[i].call+" %.1f %.1f",pp[i].cost,pp[i].balance-pp[i].cost);
System.out.println("");
}
}
}
class sum
{
//获取电话天数
public int day(String str)
{
int i,j,k,g,f;
g=j =f= 0;
j=1;
for(i=0;i<str.length();i+=j)
{
if(str.charAt(i)=='.')
g++;
if(g==2)
{
for(j = j-1;!(str.charAt(j+i)==' ');j++)
{
f =f*10+(int)(str.charAt(j+i)-48);
}
}
}
return f;
}
//计算打电话人电话位数
public int getnumberlog(String str)
{
int i,j;
j = 0;
for(i = 2;!(str.charAt(i)==' ');i++)
{
j++;
}
return j;
}
//计算座机通话费用
public double free1(int area,int time)
{
double money;
money = 0;
if(area==1)
money = 0.1*time;
if(area==2)
money = 0.3*time;
if(area==3)
money = 0.6*time;
return money;
}
//初步判断格式是否正确
public boolean isright(String str)
{
sum s =new sum();
String pattern,time1,time2;
String[] ss;
int i;
boolean f1,f2;
ss = str.split(" ");
for(i = 0;i<ss.length;i++) {
}
pattern = "^[ut]-[0-9]{11,12}.+";
if(!str.matches(pattern))
return false;
if(str.length()>20)
{
time1 = ss[i-4]+" "+ss[i-3];
time2 = ss[i-2]+" "+ss[i-1];
f1 = s.validDateTimeSimple(time1);
f2 = s.validDateTimeSimple(time2);
if(!(f1&&f2))
return false;
boolean flag1,flag2;
flag1 = true;
flag2 = true;
pattern = "^t-[0-9]{10,12}\\s([0-9]{3,4}\\s)?[0-9]{10,12}\\s([0-9]{3,4}\\s)?[0-9]{4}\\.[0-9]{1,2}\\.[0-9]{1,2}\\s[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\\s[0-9]{4}\\.[0-9]{1,2}\\.[0-9]{1,2}\\s[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}";
if(!str.matches(pattern))
return false;
}
return true;
}
public boolean validDateTimeSimple(String dateTime) {
if(dateTime == null ) {
return false;
}
DateFormat df = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
df.setLenient(false);//表示严格验证
try {
df.parse(dateTime);
} catch (ParseException e) {
return false;
}
return true;
}
//输入出现重复
public void cutit(String[] s)
{
int i,j,k;
for(i = 0;!(s[i]==null);i++)
{
for(j = i+1;!(s[j]==null);j++)
{
if(s[i].equals(s[j]))
{
for(k = j;!(s[k]==null);k++)
s[k] = s[k+1];
}
}
}
}
}
class people
{
String s;//输入的代码
String call,callphone,answerphone,calldata,answerdata;//输入电话号码
int numbersum;//输入电话号码长度
int carea,area,time,type1,type2;//呼叫电话区域 接入电话区域,通话时长,计费类型
double cost,free,where,balance;//花费金额,剩余金额
public people()
{
}
public people(String str)
{
this.balance = 100;
this.call = str;
int i;
i = (int)(str.charAt(0)-48);
if(i==0)
this.balance-= 20;
else
this.balance -= 15;
}
//获取打电话人电话号码 输入电话号码
public String getcallphone(String str)
{
// String num;
// String[] ss;
// ss = str.split(" ");
// num = ss[0].substring(2);
this.type1 = (int)(str.charAt(0)-48);
return str;
}
//获取接电话人电话号码和电话类型 输入为电话号码
public String getanswerphone(String str)
{
this.type2 = (int)(str.charAt(0)-48);
this.answerphone = str;
return str;
}
//获取接电话人区域 输入为电话号码
public void getanswerarea(String str)
{
this.area = this.thaarea(str);
}
//获取打电话人区域 输入为电话号码
public void getcallarea(String str)
{
this.carea = this.thaarea(str);
}
//获取输入打电话时间
public void getcalldata(String str1,String str2)
{
this.calldata = str1+" "+str2;
}
//获取接电话时间
public void getanswerdata(String str1,String str2)
{
this.answerdata = str1+" "+str2;
}
//计算座机电话费
public void getmoney11()
{
if(this.area==1)
this.cost += this.time*0.1;
else if(this.area==2)
this.cost += this.time*0.3;
else this.cost += this.time*0.6;
}
//计算手机打电话计费
public void getmoney12()
{
if(this.carea==1) {
if(this.area==1)
this.cost+=this.time*0.1;
else if(this.area==2)
this.cost+=this.time*0.2;
else this.cost+=this.time*0.3;
}
else if(this.carea==2)
this.cost+=this.time*0.3;
else this.cost+=this.time*0.6;
}
//手机接电话计费
public void getmoney22()
{
if(this.area==3)
this.cost+=this.time*0.3;
}
//获取通话时长
public void gettime()
{
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
this.time = 0;
try
{
Date d1 = df.parse(this.calldata);
Date d2 = df.parse(this.answerdata);
long diff = d2.getTime() - d1.getTime();//这样得到的差值是微秒级别
long days = diff / (1000 * 60 * 60 * 24);
long hours = (diff-days*(1000 * 60 * 60 * 24))/(1000* 60 * 60);
long minutes = (diff-days*(1000 * 60 * 60 * 24)-hours*(1000* 60 * 60))/(1000* 60);
int sec = (int)((diff-days*(1000 * 60 * 60 * 24)-hours*(1000* 60 * 60)-minutes*(1000*60))/(1000));
this.time =(int) (days*24*60+hours*60+minutes);
if(sec>0)
this.time+=1;
}catch (Exception e)
{
}
}
//获取电话人电话区域1:市内 2:省内 3:省外
public int thaarea(String str)
{
int i,area,n;
area = 0;
for(i = 0;i<4&&i<str.length();i++)
{
n = (int)((str.charAt(i)-48));
area = area*10+n;
}
//南昌市内
if(area==791)
return 1;
//江西省内
if(area<=799&&area>=790||area==701)
return 2;
return 3;
}
//开户
public void getpeople(people[] p,String[] s)
{
int i,j;
j = 0;
String[] ss;
for(i = 0;!(s[i+1]==null);i++)
{
if(s[i].length()<20) {
//开户,创建新的对象
ss = s[i].split(" ");
people pp = new people(ss[0].substring(2));
pp.type1 =(int)(ss[0].substring(2).charAt(0)-48);
p[j] = pp;
j++;
}
}
}
//获取打电话名单
public people[] getcallpeople(String[] s)
{
int i,j=0;
String num;
people[] ps = new people[20];
people p = new people();
for(i = 0;!(s[i]==null);i++) {
if(s[i].length()>20) {
num = p.getcallphone(s[i]);
people pp = new people(num);
pp.s = s[i];
ps[j] = pp;j++;
}
}
return ps;
}
//获取接电话名单
public people[] getanswerpeople(String[] s)
{
people[] ps = new people[20];
String num;
people p = new people();
int i,j=0;
for(i = 0;!(s[i]==null);i++) {
if(s[i].length()>20) {
num = p.getanswerphone(s[i]);
people pp = new people(num);
pp.s = s[i];
ps[j] = pp;j++;
}
}
return ps;
}
//处理信息
public void dealmeassage(people[] pp)
{
String[] ss;
int i,j=1;
for(i = 0;!(pp[i]==null);i++) {
j=1;
ss = pp[i].s.split(" ");
pp[i].callphone = pp[i].getcallphone(ss[0].substring(2));
if(ss.length==6) {
pp[i].answerphone=pp[i].getanswerphone(ss[j]);j++;
pp[i].carea = pp[i].thaarea(ss[0].substring(2));
pp[i].area = pp[i].thaarea(ss[1]);
}
else if(ss.length==7) {
if(pp[i].type1==0) {
pp[i].answerphone=pp[i].getanswerphone(ss[j]);j+=2;
pp[i].carea = pp[i].thaarea(ss[0].substring(2));
pp[i].area = pp[i].thaarea(ss[2]);
}
else {
pp[i].answerphone=pp[i].getanswerphone(ss[j+1]);j+=2;
pp[i].carea = pp[i].thaarea(ss[1]);
pp[i].area = pp[i].thaarea(ss[2]);
}
}
else {
pp[i].answerphone=pp[i].getanswerphone(ss[j+1]);j+=3;
pp[i].carea = pp[i].thaarea(ss[1]);
pp[i].area = pp[i].thaarea(ss[3]);
}
pp[i].getcalldata(ss[j], ss[j+1]);j+=2;
pp[i].getanswerdata(ss[j],ss[j+1]);
pp[i].gettime();
}
}
//计算打电话费用
public void getcallmoney(people[] pp)
{
int i;
for(i = 0;!(pp[i]==null);i++) {
if(pp[i].type1==0)
pp[i].getmoney11();
else
pp[i].getmoney12();
}
}
//计算接电话费用
public void getanswermoney(people[] pp)
{
int i;
for(i = 0;!(pp[i]==null);i++) {
if(pp[i].type2==1)
pp[i].getmoney22();
}
}
//两个电话处理
public people[] getrealpeople(people[] pp,people[] p1,people[] p2)
{
int i,j,k;
people p =new people(" ");
for(i = 0;!(pp[i]==null);i++) {
for(j = 0;!(p1[j]==null);j++) {
if(pp[i].call.equals(p1[j].callphone)) {
pp[i].cost+=p1[j].cost;
}
}
for(j = 0;!(p2[j]==null);j++) {
if(pp[i].call.equals(p2[j].answerphone)) {
pp[i].cost+=p2[j].cost;
}
}
}
p.getsetposition(pp);
p.orderset(pp);
p.orderphone(pp);
return pp;
}
//将座机全部移动到前面来
public void getsetposition(people[] pp)
{
int i,j;
people p = new people(" ");
for(i = 0;!(pp[i]==null);i++) {
for(j = i+1;!(pp[j]==null);j++) {
if(pp[i].type1==1&&pp[j].type1==0) {
p = pp[i];pp[i]=pp[j];pp[j]=p;
j--;
}
}
}
}
//将座机中电话排序 仅仅排尾号
public void orderset(people[] pp)
{
int i,j,k,n;
people p = new people(" ");
int f1=0,f2=0;
for(i = 0;!(pp[i]==null);i++) {
if(pp[i].type1==0) {
for(j = i+1;!(pp[j]==null);j++) {
for(k = 9;k<pp[i].call.length()-1;k++) {
}
f1 = (int)(pp[i].call.charAt(k)-48);
for(n = 9;n<pp[j].call.length()-1;n++) {
}
f2 =(int)(pp[j].call.charAt(n)-48);
if(f1>f2) {
p = pp[i];pp[i]=pp[j];pp[j]=p;j--;
}
}
}
}
}
//将手机电话排序 仅仅排尾号
public void orderphone(people[] pp)
{
int i,j,k,n;
people p = new people(" ");
int f1=0,f2=0;
for(i = 0;!(pp[i]==null);i++) {
if(pp[i].type1==1) {
for(j = i+1;!(pp[j]==null);j++) {
for(k = 9;k<pp[i].call.length()-1;k++) {
}
f1 = (int)(pp[i].call.charAt(k)-48);
for(n = 9;n<pp[j].call.length()-1;n++) {
}
f2 =(int)(pp[j].call.charAt(n)-48);
if(f1>f2) {
p = pp[i];pp[i]=pp[j];pp[j]=p;j--;
}
}
}
}
}
}

三:踩坑心得
1:最开始对于题目信息获取采用固定的获取方法,代码复用性不强,而且代码全是大面积相同的,而且职责划分不明显,数据传入传出很乱,两个相似的代码,一个传入是整行代码,一
个是只传入部分代码,搞的每次都要看看要传入的是啥,让脑子更糊了。
2.除了要认真写注释,还要在么一次动笔之前认真理清楚题目的意思,实现大致过程,以便于之后代码的动笔
3.虽然说作业要自主完成,但是由于对于Java里面一些函数不太了解,有时候可以借鉴借鉴同学的代码,知道一些用得着的函数,会比自己漫无目的去写高效很多,当然,不是抄同学的思
路以及代码哈,利用好网上的资源,多去看看同类型的题目,或者搜索你想要的功能,可能软件里已经有了
四:改进建议
1.注释可以多加一点,方便自己之后看得懂
2.可以多去看看优秀的代码,方便自己知道一些有用的方法,不至于用起来啥都不知道
3.可能整个代码还是比较面向过程的,之后有点改动,但是自己觉得可能还是没有完全体会面向对象的精髓,还要加强
五:总结
1.这几次比之前好多了,也是题目比较简单的原因吧,然后也知道去问问同学老师,老师指出我面向过程还是太严重,之后自己有简单改进,虽然没有那么好,但是也差不多了
同学则是获取了一些自己之前不知道的方法,自己代码效率变高,也比自己去敲代码准确度更高
2.还是那些错误,只不过在一次又一次的过程中改进了一些罢了

浙公网安备 33010602011771号