程序语言与编程实践5-> Java实践2 | 第二周作业及思路讲解 | 基础知识强化考察
是这样的,Java这门课没有给线上实验评测平台(我还专门上平台上看了看),第一周作业出得挺好,也就算了,第二周作业形式差别有点大,全是基本概念题,确实有些东西听课看书不怎么注意。既然给的是这种形式,我尽量锻炼自己不开编译器、人脑编译的能力。
一个挺好的地方:浙大的PTA测试平台
0322补充,语法确实有一些还不熟练的地方..后面的编程题挺好..
00 运行结果题
第1道
import java.io.*;
public class abc {
public static void main(String args [ ])
{
AB s = new AB("Hello!","I love JA V A.");
System.out.println(s.toString());
}
}
class AB {
String s1;
String s2;
public AB(String str1, String str2)
{
s1 = str1; s2 = str2;
}
public String toString( )
{
return s1+s2;
}
}
预期输出结果应该为:
Hello!I love JA V A.
考察的是java类、字符串的拼接、toString()函数。
第2道
import java.io.* ;
public class abc {
public static void main(String args[ ])
{
int i, s = 0 ;
int a[ ] = { 10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 , 90 };
for ( i = 0 ; i < a.length ; i ++ )
if ( a[i]%3 == 0 ) s += a[i] ;
System.out.println("s="+s);
}
}
预期结果:
s=180
考察循环与拼接符。
第3道
import java.util.Scanner;
public class abc {
public static void main(String args[ ])
{
Scanner in =new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
System.out.println("a="+a+"\nb="+b);
}
}
这道题有问题,应该输入a和b的。
预期结果:
//输入
4 5
//输出
a=4
b=5
考察拼接符吧。
第4道
public class Test {
public static void main(String[] args)
{
int percent = 10;
tripleValue(percent);
System.out.println(percent);
}
public static void tripleValue(int x)
{
x = 3 * x;
}
}
预期结果;
10
考察,java函数的内存情况,引用传参和形式传参,这道题函数调用了,但是没有返回值。
第5道
假设类 A 有构造函数 A(int a),在类 A 的其他构造函数中调用该构造函数用语句为 ( this(x) )
原因解释:书上有例子:
public Employee(String name, int age, double salary){
this.name = name;
this.age = age;
this.salary = salary;
}
public employee(){
this("刘明",25,3000);
}
//如果是其他构造函数调用构造函数,这个this语句必须是函数里的第一行;
第6道⭐
public class Test {
public static void main(String[] args)
{
new Test();
}
static int num = 4;
{
num += 3;
System.out.println("b");
}
int a = 5;
{ // 成员变量第三个
System.out.println("c");
}
Test() {
System.out.println("d");
}
static {
System.out.println("a");
}
static void run() {
System.out.println("e");
}
}
预期结果:
a
b
c
d
0322,这个没怎么看明白。
0323,看了看网上有关static执行次序的讲解1 / 讲解2 / 讲解3,类中执行顺序的优先级为:静态代码块>main>普通代码块>构造方法,静态代码块在文件被执行时,首先类就被初始化,这时候静态代码块就被执行,输出a b,newTest没有输出值,所以继续普通代码块和构造方法。
虚拟机对Java类进行首次加载时,会对静态代码块,静态成员变量,静态方法进行一次初始化加载。
-
三者的执行顺序是:静态成员变量,静态代码块,最后执行静态方法。为什么呢?方法肯定是被调用才执行,这个好说。变量和代码块呢?举例,假如代码块中用到了变量怎么办呢?所以肯定先加载成员变量。
- 调用new方法才会创建类的实例
- 类实例创建过程中,按照父子关系进行初始化。首先是初始化父类静态代码块,然后子类静态代码块。然后依次是
-
父类的初始化代码块,父类构造方法,子类初始化代码块,子类构造方法
- 类实例销毁的时候也是先销毁子类,然后是父类
- 所以我大胆推测,如果把
new Test()
去掉,那么就只有a输出 - 如果main函数里改为只有
Test.run()
,那么只有a e 输出 - 扔进编译器结果都对。<(^-^)>!
第 7 题
public class x {
private static int a;
public static void main(String[] args)
{
modify(a);
System.out.println(a);
}
public static void modify(int a)
{
a++;
}
}
预期结果:
0
0322:这个似懂非懂。
0323:从第 6 题,第 7 题页很好理解,modify函数被调用了,但是没有输出a,a此时只是形参,函数结束后a++的临时结果随着函数销毁而销毁了,没有传回main函数,所以main函数里的a还是0。
01 程序设计题
第一题
题目
请写一个程序, 类名叫 HelloWorld,类里面有一个成员方法 sayHello(),这个方法能向控制台输出 HelloWorld。
代码
package homework_week2;
/**
*
* @author zzrs123
*/
public class Homework_week2 {
public static void main(String args[]){
Helloword test = new Helloword();
// System.out.println(test);
}
private static class Helloword {
public Helloword() {
SayHello();
}
void SayHello(){
System.out.println("Helloworld");
}
}
输出结果正常。但感觉很怪,倒不是因为输出不在main函数,而是因为刚构造完对象,就结束了...
第二题
这道题有点意思。
题目
声明并测试一个复数类,其方法包括 toString() 以及复数的加减乘除运算。
代码
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package homework_week2_1;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import static java.lang.String.valueOf;
/**
*
* @author zzrs123
*/
public class Complex {
/**
* @param args the command line arguments
*/
public double real;
public double imagine;
//构造函数,后来发现必须需要一个无参构造函数
public Complex(){
this.real = 0;
this.imagine = 0;
}
public Complex(double real,double imagine){
this.real = real;
this.imagine = imagine;
}
public Complex addtwocomplex(Complex x, Complex y){
Complex sum = new Complex(x.real+y.real,x.imagine+y.imagine);
return sum;
}
public Complex subtwocomplex(Complex x,Complex y){
Complex sub = new Complex(x.real-y.real,x.imagine-y.imagine);
return sub;
}
public Complex muxtwocomplex(Complex x,Complex y){
Complex mux = new Complex(x.real*y.real-x.imagine*y.imagine, x.real*y.imagine+x.imagine*y.real);
return mux;
}
//突发奇想想算出来模平方和共轭,再来算除法
// public double squcomplex(Complex x){
// return Math.pow(x.real,2)+Math.pow(x.imagine, 2);
// }
// public Complex adjcomplex(Complex x){
// return new Complex(x.real,-x.imagine);
// }
//然后发现更麻烦了,下面的报错是因为复数类和double不能相除。要实现还得另外写函数定义这种运算
// public Complex exctwocomplex(Complex x,Complex y){
// Complex exc = muxtwocomplex(x,adjcomplex(y))/squcomplex(y);
public Complex divtwocomplex(Complex x,Complex y){
//除数不能为0
if(y.real==0&&y.imagine==0){
System.out.println("除数为0,错误");
System.exit(0);
}
else{
double real1 = x.real*y.real-x.imagine*y.imagine;
double imagine1 = x.real*y.imagine+x.imagine*y.real;
double squre = Math.pow(y.real, 2)+Math.pow(y.imagine, 2);
return new Complex(real1/squre,imagine1/squre);
}
return null;
}
public String toString(){//一定记得这里是无参的,否则复写失败
//第一次写的时候没有考虑负数以及两个都为0的情况
//想让输出的标准一点情况还挺多的
if(this.real==0.0 && this.imagine==0.0){
return valueOf(0.0);
}
else if(this.real==0.0){
return this.imagine+"i";
}
else if(this.imagine==0.0){
return valueOf(this.real);
}
else if(this.imagine < 0){
return this.real+""+this.imagine+"i";
}
else{
return this.real+"+"+this.imagine+"i";
}
//return this.real+"+"+this.imagine+"i";
}
public static void main(String args[]) throws IOException{
double a1, b1;
double a2, b2;
Scanner in = new Scanner(System.in);
a1 = in.nextDouble();
b1 = in.nextDouble();
a2 = in.nextDouble();
b2 = in.nextDouble();
Complex com1 = new Complex(a1,b1);
Complex com2 = new Complex(a2,b2);
System.out.println("你输入的两个复数是:");
System.out.println(com1.toString());
System.out.println(com2.toString());
System.out.println("两复数之和为:");
Complex add = new Complex();
add = com1.addtwocomplex(com1,com2);
System.out.println(add.toString());
System.out.println("两复数之差为: ");
Complex sub = new Complex();
sub = com1.subtwocomplex(com1, com2);
System.out.println(sub.toString());
System.out.println("两复数之积为: ");
Complex mux = new Complex();
mux = com1.muxtwocomplex(com1, com2);
System.out.println(mux.toString());
System.out.println("两复数之商为: ");
Complex div = new Complex();
div = com1.divtwocomplex(com1, com2);
System.out.println(div.toString());
}
}
02 问答题
题目
“static”关键字是什么意思?java 中是否可以覆盖(override)一个 private 或者是 static 的方法?
解答
“static”关键字修饰的成员变量或者成员方法可以直接通过类名访问。
方法重载Overloading和方法覆盖Overriding的区别:
- Overloading:两个方法的方法名相同,参数表不一样;
- Overriding:在子类中定义一个方法,正好跟父类中的一个方法一模一样(返回类型、参数表、名字),那么子类优先使用子类中的这个方法,这时候就发生了覆盖Overriding。
解答在教材《Java语言程序设计》的P129页。
父类中的static可以被继承,但不能被覆盖,如果子类定义了跟父类一模一样的方法,那么父类的static方法被隐藏。
private方法不可以覆盖,因为private修饰的变量和方法只能在当前类中使用,不能被继承和被其他的类访问。