Java实验——实验4A | 字数总计: 4.1k | 阅读时长: 17分钟 | 阅读量:
一、数组与字符串 Exam1 1、随机生成一个10个元素组成一维数组,输出数组中的最大值、最小值、所有元素总和,以及最大值和最小值在该数组中的位置,并实现数组的排序。
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package project4A;import jdk.nashorn.internal.ir.ReturnNode;import java.net.SocketTimeoutException;import java.util.Random;public class RandomRank { public static void main (String[] args) { int [] a = new int [10 ]; for (int i = 0 ; i < 10 ; i++) { int max = 100 ; a[i] = (int )(Math.random()*max); } System.out.printf("随机生成原序列:" ); for (int i:a){ System.out.printf(i+"\t" ); } System.out.println(); for (int i = 0 ; i < 9 ;i++) for (int j = i+1 ; j < 10 ;j++){ if (a[i]>a[j]){ int temp = a[i]; a[i] = a[j]; a[j] = temp; } } System.out.printf("序列排序后: " ); for (int i :a){ System.out.printf(i+"\t" ); } } }
运行结果
Exam2 2、利用arraycopy 和 copyof 方法分别实现两个数组的内容拷贝,并利用foreach语法显示两个数组元素的内容。
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package project4A;import java.lang.reflect.Array;import java.util.Arrays;public class Copy { public static void main (String[] args) { int [] arr = {1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 }; int [] copy1 = new int [10 ]; System.arraycopy(arr,1 ,copy1,2 ,6 ); System.out.println("arr数组:" ); for (int x : arr) { System.out.printf(x+"\t" ); } System.out.println(); System.out.println("copy1数组:" ); for (int x:copy1){ System.out.printf(x+"\t" ); } System.out.println(); System.out.println("copy2数组:" ); int [] copy2 = Arrays.copyOf(arr,5 ); for (int x : copy2){ System.out.printf(x+"\t" ); } } }
运行结果
Exam3 编写一个程序,完成以下功能:
声明一个名为name的String对象,内容是“My name is NetworkCrazy”
打印字符串的长度
打印字符串的第一个字符
打印字符串的最后一个字符
打印子字符串NetworkCrazy(substring()方法提取子字符串)
利用lastIndexOf()方法搜索字符 ‘e’ 最后一次出现的位置
利用StringBuffer类实现在字符缓冲区中存放字符串 “Happy new year!”,
并通过setCharAt和charAt实现字符设置和替换,利用insert实现字符的插入,利用append实现在字符串末尾添加相应的内容。
setCharAt(int index,char ch),将指定的字符ch放到index指出的位置。
charAt(int index)获得指定位置的字符
insert(int offset,char ch),在offset位置插入字符ch
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package project4A;public class StringTest { public static void main (String[] args) { String name = "My name is NetworkCrazy" ; int len = name.length(); System.out.println(name); System.out.println("The length of " +name+" is " +len); System.out.println("字符串第一个字符:" +name.charAt(0 )); System.out.println("字符串最后一个字符:" +name.charAt(len-1 )); String str1 = name.substring(name.indexOf('N' )); System.out.println(str1); System.out.println("e最后一次出现的位置为:" +name.lastIndexOf('e' )); StringBuffer stringBuffer = new StringBuffer ("Happy new year!" ); System.out.println("原:" +stringBuffer); System.out.println(stringBuffer.charAt(7 )); stringBuffer.setCharAt(7 ,'o' ); System.out.println(stringBuffer.charAt(7 )); stringBuffer.insert(14 ," yeah" ); System.out.println(stringBuffer); } }
运行结果
二、类与对象 Exam1
(1) 创建一个Rectangle 类,添加两个(private)属性
width 与height
(2)创建一个构造方法,选择 width 与height 为形式参数。
(3)在 Rectangle 类中添加两个方法计算矩形的周长和面积
创建三角形、梯形和圆形的类封装;分别定义三角形、梯形和圆形类,要求每个类中包含构造方法、求周长及面积的方法。最后在主方法main 中为三角形、梯形和圆形类创建对象并打印输出各种图形的周长及面积。(一个文件中包含三个 class 和main)
Triangle类具有类型为 double 的三个边,以及周长、面积属性,Trangle类具有返回周长、面积以及修改三个边的功能。另外,Trangle类还具有一个boolean 型的属性,该属性用来判断三个属能否构成一个三角形。
Lader类有类型double 的上底、下底、高、面积属性,具有返回面积的功能。
Circle类具有类型为 double 的半径、周长和面积属性,具有返回周长、面积的功能。
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 package project4A;public class Rectangle { private double width,height,perimeter,area; public Rectangle () { } public Rectangle (double width, double height) { this .width = width; this .height = height; } public double perimeter () { return 2 *(width+height); } public double area () { return width*height; } } class Triangle extends Rectangle { private double a,b,c,perimeter,area; private boolean isTriangle; public Triangle (double a,double b,double c) { this .a = a; this .b = b; this .c = c; if (a+b<ca+c<bb+c<a){ isTriangle = false ; } else isTriangle = true ; } @Override public double perimeter () { return a+b+c; } @Override public double area () { double p = (a+b+c)/2 ; return Math.sqrt(p*(p-a)*(p-b)*(p-c)); } public double getA () { return a; } public void setA (double a) { this .a = a; } public double getB () { return b; } public void setB (double b) { this .b = b; } public double getC () { return c; } public void setC (double c) { this .c = c; } public double getPerimeter () { return perimeter; } public void setPerimeter (double permeter) { this .perimeter = permeter; } public double getArea () { return area; } public void setArea (double area) { this .area = area; } public boolean isTriangle () { return isTriangle; } } class Lader extends Rectangle { private double topSide,buttomSide,height,area; public Lader (double topSide, double buttomSide, double height) { this .topSide = topSide; this .buttomSide = buttomSide; this .height = height; } @Override public double area () { return (topSide+buttomSide)*height/2 ; } public double getArea () { return area; } public void setArea (double area) { this .area = area; } } class Circle extends Rectangle { private double r,d,perimeter,area; public Circle (double r) { this .r = r; this .d = 2 *r; } @Override public double perimeter () { return Math.PI*d; } @Override public double area () { return Math.PI*r*r; } public double getPerimeter () { return perimeter; } public void setPerimeter (double perimeter) { this .perimeter = perimeter; } public double getArea () { return area; } public void setArea (double area) { this .area = area; } } class Test1 { public static void main (String[] args) { Rectangle rectangle = new Rectangle (10 , 20 ); System.out.println("矩形的周长为" +rectangle.perimeter()+"\t面积为" +rectangle.area()); System.out.println("======================================" ); Triangle triangle = new Triangle (3 , 4 , 5 ); if (triangle.isTriangle()){ triangle.setPerimeter(triangle.perimeter()); triangle.setArea(triangle.area()); System.out.println("此三角形的周长为" +triangle.getPerimeter()+"\t面积为" +triangle.getArea()); } else { System.out.println("三边不满足构成三角形的条件" ); } System.out.println("======================================" ); Lader lader = new Lader (5 , 9 , 3 ); lader.setArea(lader.area()); System.out.println("梯形的面积为:" +lader.getArea()); System.out.println("======================================" ); Circle circle = new Circle (10 ); circle.setPerimeter(circle.perimeter()); circle.setArea(circle.area()); System.out.println("此圆的周长为" +circle.getPerimeter()+"\t面积为" +circle.getArea()); } }
运行结果
看到题目的第一眼以为是要重写,就马上将Rectangle作为父类,Triangle、Lader、Circle作为子类,并重写周长和面积方法。
后来仔细看才知道这是两个题目,不过功能都已正常实现。
那就顺便说说重写:
重写需要有继承关系,子类重写父类的方法!
子类和父类的方法和父类必须一致,方法体不同
方法名必须相同
参数列表必须相同
修饰符: 范围可以扩大但不能缩小: public > Protected > Default > private
抛出的异常: 范围可以被缩小,但不能扩大: ClassNotFoundException > Exception(大)
为什么需要重写:
父类的功能,子类不一定需要,或者不一定满足
idea重写快捷键: Alt + Insert : override
Exam2
方法重载的练习:
编写一个程序,定义一个类,类有3个plus()方法,分别实现两个数相加,三个数相加,四个数相加的程序。
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package project4A;public class PlusTest { public static double plus (double a,double b) { return a+b; } public static double plus (double a,double b,double c) { return a+b+c; } public static double plus (double a,double b,double c,double d) { return a+b+c+d; } public static void main (String[] args) { System.out.println("100+100=" +plus(100 ,100 )); System.out.println("10.9+20.9+50.0005=" +plus(10.9 ,20.9 ,50.0005 )); System.out.println("100.9+20.1+50.00+101.9=" +plus(100.9 ,20.1 ,50.00 ,101.9 )); } }
运行结果
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
与重写不同,重载强调的是在同一个类中,对名称相同的方法进行形参的改变从而达到重载。
Exam3
编译并运行下面的程序,观察分析运行结果,体会程序super和this的用法,进一步理解变量隐藏和方法重写的概念。
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package project4A;class Person { int weight; Person(){ weight = 50 ; } void printPerson () { System.out.println("Person.printPerson()" ); } } class ZhangSan extends Person { int weight; ZhangSan(){ super (); weight = 500 ; } void printPerson () { System.out.println("ZhangSan.printPerson()" ); } void superThisUseDemo () { int weight; weight = 5000 ; super .printPerson(); printPerson(); System.out.println("super.weight=" +super .weight); System.out.println("weight=" +weight); } } public class SuperThisUseDemo { public static void main (String[] args) { ZhangSan zhangSan = new ZhangSan (); zhangSan.superThisUseDemo(); } }
直接说说主进程的运行过程吧!
1 ZhangSan zhangSan = new ZhangSan ();
这一行代码new了一个ZhangSan类的对象zhangsan,调用了ZhangSan类的无参构造,同时super()调用了Person的无参构造(这里属于显示调用父类的构造器)。
其实,在继承中,调用子类的构造方法同时都必须要调用父类的构造方法,隐性默认调用父类的无参构造,若有多重继承,则会从最高的父辈的构造方法开始调用。
super关键字其实就是父类的意思,this关键字代表本类。
调zhangsan的方法superThisUseDemo()
1 zhangsan.superThisUseDemo();
首先在此方法中定义了一个新变量weight(若未在方法中定义变量weight,则下面用的weight默认使用本类的属性weight;若在方法中定义了新变量weight,则需要用this.weight来调用类的属性weight)。
1 2 3 4 5 6 7 8 9 10 super .printPerson();printPerson(); super .weight;this .weight;weight;
运行结果
Exam4 下面的代码有什么错误,应该如何解决?
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package project4A;class Test { public static void main (String[] args) { A a = new A (); a.print(); } } class A { String s; A(String s){ this .s = s; } public void print () { System.out.println(s); } }
上例代码问题:调用了A的无参构造却没有定义A的无参构造。
解决方法:
① 在A类中添加无参构造;
② 在new对象时调用A的已定义构造方法。
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package project4A;class Test { public static void main (String[] args) { A a = new A (); a.print(); A a1 = new A ("调用了A的有参构造" ); a1.print(); } } class A { String s; A(){ s = "调用了A的无参构造" ; } A(String s){ this .s = s; } public void print () { System.out.println(s); } }
运行结果
万年历 熟悉Date类和Calendar类的成员方法
参考课本日历程序(但需修正),实现输出当前月份日历的程序(输出时要考虑上个月和下个月的天数情况),并将此程序改为万年历,可以任意输出指定月份的日历。
code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 package project4A;import project3.Exam2;import java.util.Calendar;import java.util.Scanner;public class CalendarSelf { public static int Day (int year, int month) { int i = 0 ; if ((year % 400 ) == 0 ((year % 4 == 0 ) && (year % 100 != 0 ))) { i++; } switch (month) { case 1 : return 31 ; case 2 : return 28 + i; case 3 : return 31 ; case 4 : return 30 ; case 5 : return 31 ; case 6 : return 30 ; case 7 : return 31 ; case 8 : return 31 ; case 9 : return 30 ; case 10 : return 31 ; case 11 : return 30 ; case 12 : return 31 ; default : return 0 ; } } public static void main (String[] args) { int year; int month=0 ; int day; int node; Scanner s1 = new Scanner (System.in); Scanner s2 = new Scanner (System.in); while (true ) { node = 0 ; System.out.println("请输入年份:" ); if (s1.hasNextInt()) { year = s1.nextInt(); } else break ; System.out.println("请输入月份:" ); if (s2.hasNextInt()) { month = s2.nextInt(); } day = Day(year, month); System.out.println(year+"年" +month+"月" ); Calendar instance = Calendar.getInstance(); System.out.print(" 日 \t 一 \t 二 \t 三 \t 四 \t 五 \t 六" ); instance.set(year,month-1 ,1 ); int weekday = instance.get(Calendar.DAY_OF_WEEK) - 1 ; String days[] = new String [42 ]; for (int i = 0 ; i < weekday; i++) days[i] = '[' +String.valueOf(Day(year,month-1 ) - weekday + i + 1 )+']' ; for (int i = 0 ; i < day; i++){ if (i<10 ) days[weekday + i] = ' ' +String.valueOf(i+1 )+" " ; else days[weekday + i] = ' ' +String.valueOf(i+1 )+' ' ; } while (days[node]!=null ) node++; for (int i = 1 ;node<days.length;node++,i++){ days[node] = '[' +String.valueOf(i)+"] " ; } for (int i = 0 ; i < days.length; i++) { if (i % 7 == 0 ) System.out.println(); System.out.print(days[i] + "\t" ); } System.out.println(); System.out.println(year + "年" + month + "月一共有" + day + "天" ); } } }
运行结果
GUI思路:
主体是
两个文本框(输入年月),一个按钮(作为查询按钮),
用ListTextBox或者TextBox类似的组件显示日历,代码主体与上面的代码差不多,算法一致。
汉诺塔 code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package project4A;public class HanNuo { static int step = 0 ; public static void main (String[] args) { hanioSort(3 , "A" , "B" , "C" ); } public static void hanioSort (int num ,String a ,String b ,String c) { if (num == 1 ){ move(num,a,c); } else { hanioSort(num-1 , a, c, b); move(num,a,c); hanioSort(num-1 , b, a, c); } } public static void move (int num ,String a,String b) { step ++ ; System.out.println("第" +step+"步,盘子" +num+"从" +a+"柱移到" +b+"柱" ); } }
运行结果
Java属性关键字 访问权限
public > protected > default > private
访问修饰符
同一个类
同包
不同包,子类
不同包,非子类
public
√
√
√
√
protected
√
√
√
默认(default)
√
√
private
√
对继承来来说
public和protected都是可被子类继承的,而private是不可被子类继承。
public修饰的成员可以被本类和外部类调用,也可以被继承,也可被其他包调用
protected修饰的成员与public类似,唯一不同的是protected修饰的成员无法被外包访问
private修饰的成员只能在本类调用,若要读取或设置private属性,则要使用Getter和Setter,且不可被继承。
而子类继承方式的不同也会导致继承后成员的访问权限的变化:
继承方式
基类的public成员
基类的protected成员
基类的private成员
继承引起的访问控制关系变化概括
public继承
仍为public成员
仍为protected成员
不可见
基类的非私有成员在子类的访问属性都不变
protected继承
变为protected成员
仍为protected成员
不可见
基类的非私有成员都成为子类的保护成员
private继承
变为private成员
变为private成员
不可见
基类的非私有成员都成为子类的私有成员