前言:Java面对对象学习的三条主线

  1. Java类及类的成员:属性、方法、构造器;代码块、内部类;
  2. 面向对象的三大特征:封装性、继承性、多态性(、抽样性);
  3. 其他关键字:this、super、final、abstract、interface、package、import等。

三条主线并行推进

面向过程与面向对象

面向过程与面向对象区别

  1. 面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。

  2. 面向对象:将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

面对对象的三大特征

  1. 封装(Encapsulation)

  2. 继承(Inheritance)

  3. 多态(Polymorphism)

面对对象的思想概述

  1. 程序员从面向过程的执行者转化成了面向对象的指挥者。

  2. 面对对象分析问题的思路和步骤:

    • 根据问题需要,选择问题所针对的现实世界中的实体。
    • 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
    • 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
    • 将类实例化成计算机世界中的对象,对象是计算机世界中解决问题的最终工具。

Java基本元素:类和对象

面对对象的思想概述

  1. 类(Class)和对象(Object)是面向对象的核心概念。

    • 类是对一类事物的描述,是抽象的、概念上的定义
    • 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)
  2. 万物皆对象

    • 面对对象程序设计的重点是类的设计
    • 类的设计,其实就是类的成员的设计

Java类及类的成员

  1. 现实世界的生物体,大到鲸鱼,小到蚂蚁,都是由最基本的细胞构成的。同理,Java代码世界是由诸多不同功能的类构成的。

  2. 现实生物世界中的细胞又是由什么构成的呢?细胞核、细胞质……那么,Java中用类来描述事物也是如此。常见类的成员有:

    • 属性:对应类中的成员变量
    • 行为:对应类中的成员方法

Field = 属性 = 成员变量 = 域、字段,Method = (成员)方法 = 函数

创建类的对象 = 类的实例化 = 实例化类

对象的创建和使用

面对对象思想落地的实现

package io.github.dawn333.oop;
/**
*
* @Description 一、类和对象的使用(面对对象思想落地的实现):
* 1、创建类,设计类的成员
* 2、创建类的对象
* 3、通过“对象.属性”或“对象.方法”调用对象的结构
*
* 二、如果创建了多个对象,则每个对象都独立的拥有一套属性。(非static)
* 意味着,如果改一个对象的属性a,不影响另一个对象属性a的值。
* @author DawnLee
* @version 1.0
* @data 2020-7-30 16:32:18
*
*/
public class PersonTest {
public static void main(String[] args) {
//创建Person类的对象、
Person p1 = new Person();

//调用对象的结构:属性、方法
//调用属性:对象.属性
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);

//调用方法:对象.方法
p1.eat();
p1.sleep();
p1.talk("Chinese");

//************************
Person p2 = new Person();
System.out.println(p2.name);//null

//************************
Person p3 = p1;
//将p1变量保存的地址赋给p3,导致p1和p3指向了堆空间中的同一个对象实体。
System.out.println(p3.name);//Tom
p3.age = 10;
System.out.println(p1.age);//10
}
}

class Person{
//属性
String name;
int age;
boolean isMale;

//方法
public void eat() {
System.out.println("人可以吃饭");
}
public void sleep() {
System.out.println("人可以睡觉");
}
public void talk(String language) {
System.out.println("人可以说话,使用的语言是:" + language);
}
}
  • 运行结果

内存解析

  1. 堆(heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。

  2. 通常所说的栈(stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(bolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。方法执行完,自动释放。

  3. 方法区(method area),用于存储已被虚拟机加载类信息、常量、静态变量、即时编译器编译后的代码等数据。

  4. 对象内存解析

    03对象的内存解析

内存解析的说明

  1. 引用类型的变量,只可能存储两类值:null或地址值(含变量的类型)

  2. 对象数组的内存解析

JVM内存结构

  1. 关注书籍:《JVM规范》
  2. 虚拟机栈即为平时提到的栈结构,我们将局部变量存储在栈结构中
  3. 堆,我们将new出来的结构(比如数组、对象)加载在堆空间中。补充:对象的属性(非static)加载在堆空间中。

理解“万事万物皆对象”

  1. 在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构。
    • Scanner,String等
    • 文件:File
    • 网络资源:URL
  2. 涉及到Java语言与前端HTML、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。

匿名对象的使用

  1. 理解:我们创建的对象没有显示的赋给一个变量名, 即为匿名对象。

  2. 特征:匿名对象只能代用一次。

  3. 使用:如下:

    package io.github.triabin.oop;
    /**
    *
    * @Description 匿名对象的使用
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-6 16:04:02
    *
    */
    public class InstanceTest {
    public static void main(String[] args) {
    Phone p = new Phone();

    System.out.println("正常调用:");
    p.sendEmail();
    p.playGame();

    //匿名
    System.out.println("\n匿名对象:");
    new Phone().sendEmail();
    new Phone().playGame();

    System.out.println("\n匿名对象只能代用一次:");
    new Phone().price = 1999;
    new Phone().showPrice();

    System.out.println("\n匿名对象的使用:");
    PhoneMall mall = new PhoneMall();
    // mall.show(p);
    mall.show(new Phone());
    }
    }

    class PhoneMall{
    public void show(Phone phone) {
    phone.sendEmail();
    phone.playGame();
    }
    }

    class Phone{
    double price;//价格

    public void sendEmail() {
    System.out.println("发送邮件");
    }

    public void playGame() {
    System.out.println("玩游戏");
    }

    public void showPrice() {
    System.out.println("手机的价格为:" + price);
    }
    }
    • 运行结果

    image-20200806162820788

类的成员之一:属性

类中属性的使用

属性(成员变量)与局部变量区别

  1. 相同点

    • 定义变量的格式:数据类型 变量名 = 变量值
    • 先声明,后使用
    • 变量都有其对应的作用域
  2. 不同点

    • 在类中声明的位置不同:

      • 属性:直接定义在类的一对{}内
      • 局部变量:声明在方法内、方法形参、构造器形参、构造器内部的变量
    • 关于权限修饰符

      • 属性:可以在声明属性时,指明其权限,使用权限修饰符,常用的权限修饰符有:private、public、缺省、protected —》讲封装性时再说,目前缺省即可。
      • 局部变量:不可以使用权限修饰符。
    • 默认初始化值的情况

      • 属性:类的属性,根据其类型,都有默认初始化值。
        • 整形(byte、short、int、long):0
        • 浮点型(float、double):0.0
        • 字符型(char):0(或’\u0000’)
        • 布尔型(boolean):false
        • 引用数据类型(类、数组、接口):null
      • 局部变量:没有默认初始化值,意味着在调用局部变量之前一定要显示赋值。
        • 特别地:形参在调用时,我们赋值即可,例如下列代码实例的User方法中的String language。
    • 在内存中加载的位置

      • 属性:加载到堆空间中(非static)
      • 局部变量:加载到栈空间
  3. 变量的分类二:按照在类中声明的位置

代码实例:

package io.github.triabin.oop;
/**
*
* @Description 类中属性的使用
* @author DawnLee
* @version 1.0
* @data 2020-8-5 14:49:47
*
*/
public class UserTest {
public static void main(String[] args) {
User u1 = new User();
System.out.println(u1.name);
System.out.println(u1.age);
System.out.println(u1.isMale);
u1.talk("日语");//特别的
}
}

class User{
//属性(或成员变量)
String name;
int age;
boolean isMale;

public void talk(String language) {//形参,也是局部变量
System.out.println("我们使用" + language +"进行交流。");
}

public void eat() {
String food = "烙饼";//局部变量
System.out.println("北方人喜欢吃" + food);
}
}

类的成员之二:方法

  • 方法:描述类具有的功能。比如:Math类:sqrt()\random()\……
    • Scanner类:nextXxx()……
    • Arrarys类:sort()\binarySearch()\toString()\equals()\……

类中方法的声明和使用

  1. 举例(后面的代码实例中):

    • public void eat(){}(void:没有返回值)
    • public void sleep(int hour){}
    • public String getNmae() {}(String:返回一个String类型的数据)
    • public String getNation(String nation){}
  2. 方法的声明:权限修饰符 返回值类型 方法名(形参列表){

    ​ 方法体

    ​ }

    • 注意:static、final、abstract来修饰的方法以后再讲。
  3. 说明:

    • 关于权限修饰符:目前默认方法的权限修饰符先都使用public。

    • Java规定的4种权限修饰符:private、public、缺省、protected —> 封装性再细说.

    • 返回值类型:有返回值or无返回值

      • 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中必须使用return关键字来返回指定类型的变量或常量。例如下列代码实例方法中的getName()方法。

      • 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不使用return。但是,如果使用的话,只能“return;”,表示结束此方法。

      • 我们定义方法该不该有返回值?

        ①题目要求

        ②凭经验:具体问题具体分析

    • 方法名:属于标识符,遵循表示符的规则和命名规范,“见名知意”。

    • 形参列表:方法可以声明0个,1个或多个形参。

      • 格式:数据类型1 形参1,数据类型2 形参2,…

      • 我们定义方法时要不要形参?

        ① 题目要求

        ② 凭经验,具体问题具体分析

    • 方法体:方法功能的体现。

  4. return关键字的使用:

    • 使用范围:使用在方法体中。
    • 作用:①结束方法;②针对于有返回值的方法,使用“return 数据;”方法返回所要的数据。
    • 注意:return关键字后面不可以声明执行语句。
  5. 方法的使用中可以调用当前类的属性或方法

    • 特别地:方法A中调用方法A:递归方法。
    • 方法中不能再定义方法。

代码实例

package io.github.triabin.oop;
/**
*
* @Description 类中方法的声明和使用
* @author DawnLee
* @version
* @data 2020-8-5 15:28:19
*
*/
public class CustomarTest {

}

//客户类
class Customar{
//属性:
String name;
int age;
boolean isMale;

//方法:
public void eat(){
System.out.println("客户吃饭");
}

public void sleep(int hour) {
System.out.println("休息了" + hour + "小时");
}

public String getNmae() {
if(age > 18) {
return name;
}else {//没有else则报错,必须要有一个返回值。
return "Tom";
}
}

public String getNation(String nation) {
String info = "我的国籍是:" + nation;
return info;
}
}

方法的分类(按照是否有形参及返回值)

无返回值 有返回值
无形参 void方法名(){} 返回值类型 方法名 (){}
有形参 void方法名(形参列表){} 返回值类型 方法名 (形参列表){}

练习题

练习一:创建一个Person类,其定义如下:

Person
name:String
age:int
sex:int
+study():void
+showAge():void
+addAge(int i):int

要求:

  • 创建Person类的对象,设置该对象的name、age和sex属性,调用study()方法,输出字符串“studying”,调用showAge()方法显示age值,调用addAge()方法给对象的age属性增加2岁。
  • 创建第2个对象,执行上述操作,体会同一个类的不同对象之间的关系。

Person类:

package io.github.triabin.oopexercise1;
/**
*
* @Description 类方法练习题 :创建类
* @author DawnLee
* @version 1.0
* @data 2020-8-5 19:17:39
*
*/
public class Person {
String name;
int age;
/**
* sex:1表明是男性
* sex:0表明是女性
*/
int sex;

public void study() {
System.out.println("studying");
}

public void showAge() {
System.out.println("age:" + age);
}

public int addAge(int i) {
age += i;
return age;
}
}

调用类:

package io.github.triabin.oopexercise1;
/**
*
* @Description 类方法练习题:测试(调用)创建的方法
* @author DawnLee
* @version 1.0
* @data 2020-8-5 19:24:37
*
*/
public class PersonTest {
public static void main(String[] args) {
/**
* (1)创建Person类的对象,设置该对象的name、age和sex属性,调用study()方法,
* 输出字符串“studying”,调用showAge()方法显示age值,调用addAge()方法给对
* 象的age属性增加2岁。
*/
Person p1 = new Person();

//调用属性
p1.name = "Tom";
p1.age = 18;
p1.sex = 1;

//调用方法
p1.study();
p1.showAge();
int newAge = p1.addAge(2);
System.out.println(p1.name + "新年龄为:" + newAge);

/**
* (2)创建第2个对象,执行上述操作,体会同一个类的不同对象之间的关系。
*/
Person p2 = new Person();
p2.study();
p2.showAge();
p2.addAge(2);
p2.showAge();
}
}
  • 运行结果

tips:在同一个包(package)里面,类方法可以分开写然后正常创建类的对象。

练习二

package io.github.triabin.oopexercise1;
/**
*
* @Description 利用面向对象的编程方法,设计类Circle计算圆的面积。
* @author DawnLee
* @version 1.0
* @data 2020-8-5 20:09:00
*
*/
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
c1.radius = 2.1;

//对应方式一:
// double area = c1.findArea();
// System.out.println(area);

//对应方式二:
c1.findArea();
}
}

class Circle{
//属性
double radius;

//方式一:有返回值
// public double findArea() {
// double area = Math.PI * radius * radius;
// return area;
// }

//方式二:无返回值
public void findArea() {
double area = Math.PI * radius * radius;
System.out.println("面积为:" + area);
}
}
  • 运行结果

练习三

package io.github.triabin.oopexercise1;
/**
*
* @Description 3.1 编写程序,声明一个method方法,在方法中打印一个10*8的*型矩形,在main方法中调用改方法。
* 3.2 修改上一个程序,在method方法中,除打印一个10*8的*型矩形外,再计算该矩形的面积,并将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。
* 3.3 修改上一个程序,在method方法中提供m和n两个参数,方法中打印一个m*n的*型矩形,并计算该矩形的面积,将其作为方法返回值。在main函数种调用该方法,接收返回的面积值并打印。
* @author DawnLee
* @version
* @data 2020-8-5 20:35:29
*
*/
public class Exercise3 {
public static void main(String[] args) {
Exercise3 test = new Exercise3();

//3.1 测试:
//test.method();

//3.2 测试:
//方式一:
// int area = test.method();
// System.out.println("面积为:" + area);
//方式二:
// System.out.println("面积为:" + test.method());

//3.3 测试
int area = test.method(12, 10);
System.out.println("面积为:" + area);
}

// 3.1:
// public void method() {
// for(int i = 0;i < 8;i++) {
// for(int j = 0;j < 10;j++) {
// System.out.print("* ");
// }
// System.out.println();
// }

// 3.2:
// public int method() {
// for(int i = 0;i < 8;i++) {
// for(int j = 0;j < 10;j++) {
// System.out.print("* ");
// }
// System.out.println();
// }
// return 10 * 8;
// }

// 3.3:
public int method(int m,int n) {
for(int i = 0;i < n;i++) {
for(int j = 0;j < m;j++) {
System.out.print("* ");
}
System.out.println();
}
return m * n;
}
}
  • 3.1:

  • 3.2

  • 3.3

练习四

package io.github.triabin.oopexercise1;
/**
*
* @Description 4.对象数组题目:
* 定义类Student,包含3个属性:学号number(int),年级state(int),成绩score(int)。创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
* 问题一:打印出3年级(state值为3)的学生信息。
* 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生。
* 提示:
* 1)生成随机数:Math.random(),返回值类型double;
* 2)四舍五入取整:Math.round(double d),返回值类型long。
* @author DawnLee
* @version
* @data 2020-8-5 21:48:01
*
*/
public class Exercise4 {
public static void main(String[] args) {
//声明Student类型的数组
Student[] stu = new Student[20];
for(int i = 0;i < stu.length;i++) {
//给数组元素赋值
stu[i] = new Student();
//Student对象的属性赋值
stu[i].number = (i + 1);
stu[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);//6个年级
stu[i].score = (int)(Math.random() * (100 - 0 + 1) + 0);
}
for(int i = 0;i < stu.length;i++) {
System.out.println(stu[i].info());
}

//问题一:打印出3年级(state值为3)的学生信息:
System.out.println("********************");
for(int i = 0;i < stu.length;i++) {
if(stu[i].state == 3) {
System.out.println(stu[i].info());
}
}

//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生。
System.out.println("********************");
for(int i = 0;i < stu.length - 1;i++) {
for(int j = 0;j < stu.length -1 -i;j++) {
if(stu[j].score > stu[j + 1].score) {
//如果需要换序交换的是数组元素:Student对象!!!
Student temp = stu[j];
stu[j] = stu[j + 1];
stu[j + 1] = temp;
}
}
}
for(int i = 0;i < stu.length;i++) {
System.out.println(stu[i].info());
}
}
}

class Student{
int number;//学号
int state;//年级
int score;//成绩

//显示学生信息方法
public String info() {
return "学号:" + number + "," + "年级:" + state + "," + "成绩:" + score;
}
}
  • 运行结果:
  • 优化:将各个重复性操作封装成方法
package io.github.triabin.oopexercise1;
/**
*
* @Description 4.对象数组题目:
* 定义类Student,包含3个属性:学号number(int),年级state(int),成绩score(int)。创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
* 问题一:打印出3年级(state值为3)的学生信息。
* 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生。
* 提示:
* 1)生成随机数:Math.random(),返回值类型double;
* 2)四舍五入取整:Math.round(double d),返回值类型long。
* @author DawnLee
* @version 2.0
* @data 2020-8-5 21:48:01
*
*/
public class Exercise4 {
public static void main(String[] args) {
//声明Student类型的数组
Student[] stu = new Student[20];
for(int i = 0;i < stu.length;i++) {
//给数组元素赋值
stu[i] = new Student();
//Student对象的属性赋值
stu[i].number = (i + 1);
stu[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);//6个年级
stu[i].score = (int)(Math.random() * (100 - 0 + 1) + 0);
}
Exercise4 test = new Exercise4();
//遍历学生数组
test.print(stu);

//问题一:打印出3年级(state值为3)的学生信息:
System.out.println("********************");
test.searchState(stu, 3);

//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生。
System.out.println("********************");
test.sort(stu);
test.print(stu);
}

//遍历数组的方法
public void print(Student[] stu) {
for(int i = 0;i < stu.length;i++) {
System.out.println(stu[i].info());
}
}

/**
*
* @Description 查找Student数组中指定年级的学生信息
* @author Dawn Lee
* @version 2.0
* @data 2020-8-522:44:37
*
* @param stu 要查找的数组
* @param state 要找的年级
*/
public void searchState(Student[] stu, int state) {
for(int i = 0;i < stu.length;i++) {
if(stu[i].state == state) {
System.out.println(stu[i].info());
}
}
}

/**
*
* @Description 给Student数组排序
* @author Dawn Lee
* @version
* @data 2020-8-522:47:31
* @param stu
*/
public void sort(Student[] stu) {
for(int i = 0;i < stu.length - 1;i++) {
for(int j = 0;j < stu.length -1 -i;j++) {
if(stu[j].score > stu[j + 1].score) {
//如果需要换序交换的是数组元素:Student对象!!!
Student temp = stu[j];
stu[j] = stu[j + 1];
stu[j + 1] = temp;
}
}
}
}
}

class Student{
int number;//学号
int state;//年级
int score;//成绩

//显示学生信息方法
public String info() {
return "学号:" + number + "," + "年级:" + state + "," + "成绩:" + score;
}
}

Tips:面试遇到举例说明类和对象的关系时尽量举开发中的例子。

再谈方法

方法的重载

  1. 定义

    • 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
      • “两同一不同”:同一个类、相同的方法名;参数列表不同:参数个数不同、参数类型不同。
  2. 特点

  • 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
  1. 示例

    • Arrays类中重载的sort() / binarySearch()
    package io.github.triabin.methodagain;
    /**
    *
    * @Description 方法重载举例
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-6 18:51:26
    *
    */
    public class OverLoadTest {
    public static void main(String[] args) {
    OverLoadTest test = new OverLoadTest();
    test.getSum(1,2);
    }

    //如下4个方法构成了重载
    public void getSum(int i,int j) {
    System.out.println("1");
    }

    public void getSum(double d1, double d2) {
    System.out.println("2");
    }

    public void getSum(String s, int i) {
    System.out.println("3");
    }

    public void getSum(int i,String s) {
    System.out.println("4");
    }

    // public int getSum(int i,int j) {
    // return 0;
    // }

    // public void getSum(int m,int n) {
    //
    // }
    }

    Tips:支持自动类型提升,例如,如果形参为double型,但是输入的形参为int型,则自动将int型转换为double型。

  2. 判断是否是重载

  • 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系,只看形参数目和类型
  1. 通过对象调用方法时,如何确定某一个指定的方法:

    • 方法名 —> 参数列表

练习题

练习题一

  • 编写程序,定义三个重载方法并调用。方法名为mOL。
    • 三个方法分别接收一个int参数、两个int参数、一个字符串参数。分别执行平方运算并输出结果、相乘并输出结果、输出字符串信息。
    • 在主类的main方法中分别用参数区别调用三个方法。
package io.github.triabin.methodagain;
/**
*
* @Description 定义三个重载方法并调用
* @author DawnLee
* @version 1.0
* @data 2020-8-6 19:36:02
*
*/
public class OverLoadEx1 {
public static void main(String[] args) {
OverLoadEx1 m = new OverLoadEx1();
m.mOL(2);
m.mOL(2, 5);
m.mOL("字符串");
}

public void mOL(int i) {
System.out.println(i * i);
}

public void mOL(int i,int j) {
System.out.println(i * j);
}

public void mOL(String s) {
System.out.println(s);
}
}

练习题二

  • 定义三个重载方法max(),第一个方法求两个int值中的最大值,第二个方法求两个double值中的最大值,第三个方法求三个double值中的最大值,分别调用三个方法。
package io.github.triabin.methodagain;
/**
*
* @Description 重载方法练习二
* @author DawnLee
* @version 1.0
* @data 2020-8-6 19:50:35
*
*/
public class OverLoadEx2 {
public static void main(String[] args) {
OverLoadEx2 test = new OverLoadEx2();
test.max(1, 3);
test.max(1.5, 3.5);
test.max(1.5, 3.5, 7.5);
}

public void max(int i,int j) {
System.out.println("第一个方法求得最大值为:" + ((i > j)? i : j));
}
public void max(double i,double j) {
System.out.println("第二个方法求得最大值为:" + ((i > j)? i : j));
}
public void max(double i,double j,double k) {
System.out.println("第三个方法求得最大值为:" + ((((i > j)? i : j) > k)? ((i > j)? i : j) : k));
}
}

可变个数的形参

  1. JavaSE 5.0中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。

    • JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量

      public static void test(int a,String[] books);

    • JDK 5.0:采用可变个数形参来定义方法,传入多个同一类型变量

      public static void test(int a,String...books);

  2. 具体使用:

    • 可变个数形参的格式:数据类型 … 变量名
    • 当调用可变个数形参的方法时,传入的参数个数可以是:0个、1个、2个……
    • 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。
    • 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不够成重载(即二者不能共存)。
    • 可变个数形参在方法的形参列表中,必须声明在末尾。
    • 可变个数形参在方法的形参列表中,最多只能声明一个可变形参。
  3. 示例

    package io.github.triabin.methodagain;
    /**
    *
    * @Description 可变个数的形参具体使用
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-6 20:29:02
    *
    */
    public class VarAgu {
    public static void main(String[] args) {
    VarAgu test = new VarAgu();
    test.show(12);
    test.show("Hello");
    test.show("Hello","world");
    test.show();

    // test.show(new String[] {"AA","BB","CC"});//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量,JDK 5.0向前兼容,所以(String ... strs)同样可以用此方法传入形参
    test.show("AA","BB","CC");
    }

    public void show(int i) {
    System.out.println("show(int i)");
    }

    public void show(String s) {
    System.out.println("show(String)");
    }

    public void show(String ... strs) {
    System.out.println("show(String ... strs)");
    //调用
    for(int i = 0;i < strs.length;i++) {
    System.out.println(strs[i]);
    }
    }

    // public void show(String[] strs) {//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量
    // System.out.println("show(String[] strs)");
    // }
    }
    • 运行结果

方法参数的值传递机制

变量的值传递机制

  1. 关于变量的赋值:

    如果是基本数据类型,此时赋值的是变量所保存的数据值;

    如果变量是引用数据类型,此时,赋值的是变量所保存的数据的地址值。

  2. 示例

    package io.github.triabin.methodagain;
    /**
    *
    * @Description 方法参数的值传递机制
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-6 21:03:46
    *
    */
    public class ValueTransfer {
    public static void main(String[] args) {
    System.out.println("******基本数据类型的值传递情况******");
    int m = 10;
    int n = m;
    System.out.println("m = " + m + ", n = " + n);
    n = 20;
    System.out.println("m = " + m + ", n = " + n);

    System.out.println("******引用数据类型的值传递情况******");
    Order o1 = new Order();
    o1.orderID = 1001;
    Order o2 = o1;//赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体。
    System.out.println("o1.orderID = " + o1.orderID + ", o2.orderID = " + o2.orderID);
    o2.orderID = 1002;
    System.out.println("o1.orderID = " + o1.orderID + ", o2.orderID = " + o2.orderID);
    }
    }

    class Order{
    int orderID;
    }
    • 运行结果

方法的形参传递机制:值传递

  1. 形参:方法定义时,声明的小括号内的参数。

    实参:调用方法时实际传递给形参的数据。

  2. 值传递机制

    如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值;

    如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值

  3. 示例

    package io.github.triabin.methodagain;
    /**
    *
    * @Description 法的形参传递机制:值传递
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-6 21:52:21
    *
    */
    public class ValueTransfer01 {
    public static void main(String[] args) {
    int m = 10;
    int n = 20;
    System.out.println("m = " + m + ", n = " + n);
    //交换两个变量值的操作
    // int temp = m;
    // m = n;
    // n = temp;
    ValueTransfer01 test = new ValueTransfer01();
    test.swap(m, n);//未能交换,原因看内存解析。
    System.out.println("m = " + m + ", n = " + n);
    }


    public void swap(int m,int n) {
    int temp = m;
    m = n;
    n = temp;
    }
    }
    • 执行结果
    • 内存解析(交换失败原因)
    package io.github.triabin.methodagain;

    public class ValueTransfer02 {
    public static void main(String[] args) {
    Data data = new Data();
    data.m = 10;
    data.n = 20;
    System.out.println("m = " + data.m + ",n = " + data.n);

    //交换m和n的值
    // int temp = data.m;
    // data.m = data.n;
    // data.n = temp;
    ValueTransfer02 test = new ValueTransfer02();
    test.swap(data);
    System.out.println("m = " + data.m + ",n = " + data.n);
    }

    public void swap(Data data) {
    int temp = data.m;
    data.m = data.n;
    data.n = temp;
    }
    }


    class Data{
    int m;
    int n;
    }
    • 运行结果
    • 内存解析

练习题

例题一:方法的参数传递

package io.github.triabin.methodagain;
/**
*
* @Description 值传递机制练习一
* @author DawnLee
* @version 1.0
* @data 2020-8-7 8:27:37
*
*/
public class ValueTransferEx01 {
public static void main(String[] args) {
ValueTransferEx01 test = new ValueTransferEx01();
test.first();
}
public void first(){
int i = 5;
Value v = new Value();
v.i = 25;
second(v,i);
System.out.println(v.i);
}
public void second(Value v,int i){
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println(v.i + " " + i);
}
}


class Value{
int i = 15;
}
  • 输出结果

    15 0

    20

  • 内存解析

练习二

package io.github.triabin.methodagain;
/**
*
* @Description 值传递机制练习二
* @author DawnLee
* @version 1.0
* @data 2020-8-7 8:48:21
*
*/
public class ValueTransferEx02 {
public static void main(String args[]){
ValueTransferEx02 test = new ValueTransferEx02();
int a = 10;
int b = 10;
test.method(a,b);//需要在method方法被调用之后,仅打印出a = 100,b = 200,请写出method方法的代码
System.out.println("a = " + a);
System.out.println("b = " + b);
}
//代码编写处

//方法一
public void method(int a,int b){
a = 10 * a;
b = 20 * b;
System.out.println("a = " + a);
System.out.println("b = " + b);
System.exit(0);//直接退出程序,不再执行后续步骤
}

//方法二:对输出流做处理,以后再学
}

注意:本题不是考察方法的参数传递,只是一个易混淆思考方向的题目

练习三:将对象作为参数传递给方法

  1. 定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()返回圆的面积。

  2. 定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下:public void printAreas(Circle c, int time)

    在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积。例如,time为5,输出半径为1,2,3,4,5及其对应的圆面积。

  3. 在main方法中调用printAreas(),调用完毕后输出当前半径值。程序运行结果如图所示:

    package io.github.triabin.methodagain;
    /**
    *
    * @Description 值传递机制练习三
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-7 9:30:36
    *
    */
    public class ValueTransferEx03 {
    public static void main(String[] args) {
    PassObject test = new PassObject();
    Circle c = new Circle();
    int time = 5;
    test.printAreas(c, time);
    System.out.println("now radius is:" + c.radius);
    }
    }


    class Circle{
    double radius = 0;

    public double findArea() {
    return Math.PI * radius * radius;
    }
    }


    class PassObject{
    public void printAreas(Circle c,int time) {
    System.out.println("Radius\t\tArea");
    for(double i = 1;i <= time;i++) {
    c.radius = i;
    System.out.println(c.radius + "\t\t" + c.findArea());
    }
    c.radius = time + 1;
    }
    }
    • 运行结果

递归(recursion)方法

  1. 递归方法:一个方法体内调用自身。

  2. 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无需循环控制。递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

  3. 示例

    package io.github.triabin.methodagain;
    /**
    *
    * @Description 递归方法示例
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-7 15:04:41
    *
    */
    public class RecursionIns {
    public static void main(String[] args) {
    //计算1-100内所有数的和
    //方式一
    int sum1 = 0;
    for(int i = 1;i <= 100;i++) {
    sum1 += i;
    }
    System.out.println("方式一:" + sum1);

    //方式二(递归):
    RecursionIns test = new RecursionIns();
    int sum2 = test.getSum(100);
    System.out.println("方式二:" + sum2);

    //计算阶乘
    int n = 5;
    int fac = test.getFac(n);
    System.out.println(n + "的阶乘为:" + fac);
    }

    //计算1-100内所有数的和的方法
    public int getSum(int n) {
    if(n == 1) {
    return n;
    }else {
    return n + getSum(n - 1);
    }
    }

    //计算1-n之间的乘积:n!
    public int getFac(int n) {
    if(n == 1) {
    return n;
    }else {
    return n * getFac(n - 1);
    }
    }
    }
    • 运行结果

练习题

练习一

  • 已知有一个数列:f(0) = 1,f(1) = 4,f(n+2) = 2*f(n+1) + f(n),其中n是大于0的整数,求f(10)的值。
package io.github.triabin.methodagain;
/**
*
* @Description 已知有一个数列:f(0) = 1,f(1) = 4,f(n+2) = 2*f(n+1) + f(n),
* 其中n是大于0的整数,求f(10)的值。
* @author DawnLee
* @version 1.0
* @data 2020-8-7 15:33:08
*
*/
public class RecursionEx01 {
public static void main(String[] args) {
RecursionEx01 test = new RecursionEx01();
System.out.println("f(10) = " + test.f(10));
}

public int f(int n) {
if(n == 0) {
return 1;
}else if(n == 1) {
return 4;
}else {
return 2*f(n - 1) + f(n - 2);
}
}
}
  • 运行结果

练习二:斐波那契数列(Fibonacci)

  • 输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值1 1 2 3 5 8 13 21 34 55。

    规律:一个数等于前两个数之和。

    要求:计算斐波那契数列的第n个值,并将整个数列打印出来。

package io.github.triabin.methodagain;
import java.util.Scanner;
/**
*
* @Description 计算斐波那契数列第n个值并打印
* @author DawnLee
* @version 1.0
* @data 2020-8-7 15:58:39
*
*/
public class RecursionEx02 {
public static void main(String[] args) {
RecursionEx02 test = new RecursionEx02();
Scanner input = new Scanner(System.in);
System.out.println("要打印斐波那契数列前几位?(输入任意大于0的整数)");
int n = input.nextInt();
for(int i = 1;i <= n;i++) {
System.out.print(test.f(i) + " ");
}
System.out.println();
input.close();
}

public int f(int n) {
if(n == 1) {
return 1;
}else if(n == 2) {
return 1;
}else {
return f(n - 1) + f(n - 2);
}
}
}
  • 运行结果

章节练习

  1. 什么是方法重载?

    “两同一不同”:同一个类、相同的方法名;参数列表不同。

  2. 说明Java方法中的参数传递机制的具体体现。

    基本数据类型:数据值

    引用数据类型:地址值(含变量的数据类型)例:

    Person p1 = new Person();

    User u1 = p1;//编译错误

  3. 成员变量和局部变量在声明的位置上是否有默认初始化值?

  4. 谈谈return关键字的使用。

    ①结束方法

    ②针对于有返回值的方法,return + 返回数据;

  5. 拓展:宋老师,我今天去百度面试,遇到一个双重递归调用的问题,我琢磨了一下,完全不知道为什么。打断点了,也还是没看懂程序为什么会那样走。您有空可以看一下,求指教。

    /**
    * 测试递归调用的次数
    */
    @test
    public void binomial(){ recursion(10); }

    private static int recursion(int k){
    count++;
    System.out.println("count1:" + count + " k:" + k);
    if(k <= 0){
    return 0;
    }
    return recursion(k - 1) + recursion(k - 2);//287
    //return recursion(k - 1);//11
    //return recursion(k - 1) + recursion(k - 1);//2047
    }
    • 图解

OOP特征一:封装与隐藏

  • OOP,即Object oriented programming,面向对象编程。

引入

  1. 为什么需要封装?封装的作用和含义?
    • 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部结构吗?有必要碰电动机吗?
    • 我要开车……
  2. 我们程序设计追求“高内聚,低耦合”。
    • 高内聚:类的内部操作细节自己完成,不允许外部干涉;
    • 低耦合:仅对外暴露少量的方法用于使用。
  3. 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

信息的封装和隐藏

  • 当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里,赋值的操作要受属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们需要给属性赋值加入额外的条件。这个条件就不能再属性声明时体现,我们只能通过方法进行限制条件的添加。(比如,示例中的setLegs()方法)同时,我们需要避免用户再使用“对象.属性”的方式对属性进行赋值。则需要将属性声明为私有的(private)。

    –> 此时,针对属性就体现了封装性。

  1. 封装性的体现:我们讲类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值。

  2. 拓展:封装性的体现

    ①如上 ②不对外暴露的私有的方法 ③单例模式 …

  3. 示例

package top.triabin.encapsulationconcealment;
/**
*
* @Description 封装与隐藏示例
* @author DawnLee
* @version 1.0
* @data 2020-8-8 9:04:49
*
*/
public class InsAnimal {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "大黄";
//a.age = 1;//age属性私有后无法赋值,通过setAge()方法来赋值
a.setAge(1);
//a.legs = 4;//The field Animal.legs is not visible(不可见)
a.setLegs(4);
a.show();

System.out.println();
a.setLegs(6);
a.show();

System.out.println();
a.setLegs(-2);
a.show();


}
}


class Animal{
String name;
private int age;
private int legs;//私有权限修饰符,使得外界不能直接调用legs这个参数,只能通过规定的方式(setLegs())来设置legs属性的值

//筛选合理赋值
public void setLegs(int l) {
if(l >= 0 && l % 2 == 0) {
legs = l;
}else{
legs = 0;
//抛出一个异常(暂时没有讲)
}
}

//legs被私有化以后用它来获取当前legs属性
public int getLegs() {
return legs;
}

public void eat() {
System.out.println("动物进食");
}

public void show() {
System.out.println("name:" + name + ",age:" + age + ", legs:" + legs);
}

//提供属性age的get和set方法
public int getAge() {
return age;
}
public void setAge(int n) {
age = n;
}
}
  • 运行

四种访问权限修饰符

  • 封装性的体现,需要权限修饰符来配合
  1. Java规定的种权限(从小到大排列):private、缺省、protected、public

  2. Java的权限修饰符public、protected、private置于类的成员定义前,用来限定对象对该类成员的访问权限。

  3. 4种权限修饰符可以用来修饰类及类的内部结构:属性、方法、构造器、内部类。

  4. 具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类;修饰类只能用default(缺省)、public。

  5. 代码示例

    同一个包不同的类里面

    package top.triabin.encapsulationconcealment;
    /**
    *
    * @Description 权限修饰符使用测试(同包不同类)
    * @author DawnLee
    * @version
    * @data 2020-8-8 10:58:12
    *
    */
    public class PromissionInsTest {
    public static void main(String[] args) {
    PermissionIns order = new PermissionIns();

    System.out.print(order.orderDefault + " ");
    System.out.println(order.orderPublic);
    //出了PromissionIns类以后,私有结构就不可以调用了。
    // System.out.println(order.orderPrivate);//报错:The field PermissionIns.orderPrivate is not visible

    //方法也类似
    System.out.println();
    order.methodDefault();
    order.show();
    order.methodPublic();
    //出了PromissionIns类以后,私有结构就不可以调用了。
    // order.methodPrivate;
    order.show();
    }
    }

    同一个Project不同的包里面

    package top.triabin.prossiontest;

    import top.triabin.encapsulationconcealment.PermissionIns;

    /**
    *
    * @Description 权限修饰符使用测试(不同的包)
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-8 11:43:11
    *
    */
    public class PromissionClassTest {
    public static void main(String[] args) {
    PermissionIns order = new PermissionIns();

    System.out.println(order.orderPublic);
    //出了PromissionIns类所属的包以后,私有结构、缺省声明的结构都不可以用了
    // System.out.print(order.orderDefault + " ");
    // System.out.println(order.orderPrivate);//报错:The field PermissionIns.orderPrivate is not visible

    //方法也类似
    System.out.println();
    //出了PromissionIns类所属的包以后,私有结构、缺省声明的结构都不可以用了
    // order.methodDefault();
    order.show();
    order.methodPublic();
    //出了PromissionIns类以后,私有结构就不可以调用了。
    // order.methodPrivate;
    order.show();
    }
    }

  6. 总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构的在被调用时的可见性大小。

章节练习

创建程序,在其中定义两个类:Person和PersonTest类。定义如下:用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。在PersonTest类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。

Person
-age:int
+setAge(i:int)
+getAge():int
package top.triabin.encapsulationconcealment;
/**
*
* @Description 体会Java的封装性
* @author DawnLee
* @version 1.0
* @data 2020-8-8 12:05:21
*
*/
public class PersonTest {
public static void main(String[] args) {
Person b = new Person();
System.out.println("设置前年龄为:" + b.getAge());
b.setAge(100);
System.out.println("设置后年龄为:" + b.getAge());

System.out.print("\n范围限定测试:");
b.setAge(-10);
}
}

class Person{
private int age;

public int getAge() {
return age;
}
public void setAge(int i) {
if(i >= 0 && i <= 130) {
age = i;
}else {
// throw new RuntimeException("传入的数据非法!");
System.out.println("传入的数据非法!");
}
}
}
  • 运行

类的成员之三:构造器(或构造方法)

构造器的作用

  1. 创建对象

  2. 初始化对象的信息

  3. 示例

    package top.triabin.constructor;
    /**
    *
    * @Description 类的结构之三:构造器(或构造方法、constructor)的使用
    * @author DawnLee
    * @version
    * @data 2020-8-8 14:52:46
    *
    */
    public class PersonTest {
    public static void main(String[] args) {
    //创建类的对象:new + 构造器
    Person p = new Person();
    p.eat();

    Person p1 = new Person("Tom");
    System.out.println(p1.name);
    }
    }

    class Person{
    //属性
    String name;
    int age;

    //构造器
    public Person() {
    System.out.println("Person()....");
    }
    public Person(String n) {
    name = n;
    }

    //方法
    public void eat() {
    System.out.println("人吃饭");
    }
    public void study() {
    System.out.println("人可以学习");
    }
    }
    • 运行

说明

  1. 如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器。
  2. 定义构造器的格式:权限修饰符 类名(形参列表){}。
  3. 一个类中定义多个构造器,彼此构成重载。
  4. 一旦我们显式定义了构造器之后,系统就不再提供默认的空参构造器。
  5. 一个类中,至少会有一个构造器。

练习

  1. 在前面定义的Person类中添加构造器,利用构造器设置所有人的age属性初始值都为18。

    //构造器
    public Person(){
    age = 18;
    }
  2. 修改上题中的类和构造器,增加name属性,使得每次创建Person对象的同时初始化对象的age属性值和name属性值。

    Person
    -name:String
    +setName(i:String)
    +getName():String
    package top.triabin.constructor;
    /**
    *
    * @Description 练习题第2题
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-8 15:27:46
    *
    */
    public class PersonEx02 {
    public static void main(String[] args) {
    //创建类的对象:new + 构造器
    Person p = new Person("Tom",21);
    System.out.println("姓名:" + p.getName() + "\n年龄:" + p.age);
    }
    }

    class Person{
    private String name;
    int age;

    public Person(String n,int a) {
    name = n;
    age = a;
    }

    public void setName(String n) {
    name = n;
    }
    public String getName() {
    return name;
    }
    }
    • 运行
  3. 编写两个类,TriAngle和TriAngleTest,其中TriAngle类中声明私有的底边长base和高height,同时声明公共方法访问私有变量。此外,提供类必要的构造器。另一个类中使用这些公共方法,计算三角形面积。

    在同一个包下,两个类分开创建。

    • TriAngle类
    package top.triabin.constructor;
    /**
    *
    * @Description TriAngle类中声明私有的底边长base和高height,同时声明公共方法访问私有变量。此外,提供类必要的构造器。
    * @author DawnLee
    * @version
    * @data 2020-8-8 15:43:13
    *
    */
    public class TriAngle {
    private double base;
    private double height;


    public TriAngle() {
    //开发时习惯上提供一个空参
    }
    public TriAngle(double b,double h) {
    base = b;
    height = h;
    }


    public void setBase(double b) {
    base = b;
    }
    public double getBase() {
    return base;
    }

    public void setHeight(double h) {
    height = h;
    }
    public double getHeight() {
    return height;
    }
    }
    • TriAngleTest类
    package top.triabin.constructor;
    /**
    *
    * @Description 另一个类中使用这些公共方法,计算三角形面积。
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-8 15:54:34
    *
    */
    public class TriAngleTest {
    public static void main(String[] args) {
    System.out.println("方式一:调用空参的构造器");
    TriAngle t1 = new TriAngle();
    t1.setBase(2.0);
    t1.setHeight(2.4);
    System.out.println("三角形的底边长为" + t1.getBase() + ",高为" + t1.getHeight() + ",所以面积为" + (t1.getBase() * t1.getHeight() / 2) + "。\n");

    System.out.println("方式二:调用带参的构造器");
    TriAngle t2 = new TriAngle(2.0,2.4);
    System.out.println("三角形的底边长为" + t2.getBase() + ",高为" + t2.getHeight() + ",所以面积为" + (t2.getBase() * t2.getHeight() / 2) + "。\n");
    }
    }
    • 运行
  4. 定义Student类,有4个属性:String name、int age、String school、String major。定义Student类的3个构造器:

    ①第一个构造器Student(String n,int a)设置类的name和age属性;

    ②第二个构造器Student(String n,int a, String s)设置类的name,age和school属性;

    ③第三个构造器Student(String n,int a,String s,String m)设置类的name,age,school和major属性。

    在main方法中分别调用不同的构造器创建对象,并输出器属性值。

    package top.triabin.constructor;
    /**
    *
    * @Description 课后练习三
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-8 18:35:25
    *
    */
    public class StudentEx03 {
    public static void main(String[] args) {
    Student s = new Student();
    System.out.println("name:" + s.name + "\tage:" + s.age + "\tschool:" + s.school + "\tmajor:" + s.major);

    Student s1 = new Student("Triabin",18);
    System.out.println("name:" + s1.name + "\tage:" + s1.age + "\tschool:" + s1.school + "\tmajor:" + s1.major);

    Student s2 = new Student("Triabin",18,"SUES");
    System.out.println("name:" + s2.name + "\tage:" + s2.age + "\tschool:" + s2.school + "\tmajor:" + s2.major);

    Student s3 = new Student("Triabin",18,"SUES","BTE");
    System.out.println("name:" + s3.name + "\tage:" + s3.age + "\tschool:" + s3.school + "\tmajor:" + s3.major);
    }
    }


    class Student{
    String name;
    int age;
    String school;
    String major;

    public Student() {
    //空参
    }
    public Student(String n,int a) {
    name = n;
    age = a;
    }
    public Student(String n,int a,String s) {
    name = n;
    age = a;
    school = s;
    }
    public Student(String n,int a,String s,String m) {
    name = n;
    age = a;
    school = s;
    major = m;
    }
    }
    • 运行

总结:属性赋值的先后顺序

package top.triabin.constructor;
/*
* 总结:属性赋值的先后顺序
* ①默认初始化
* ②显式初始化
* ③构造器中初始化
* ④通过"对象.方法"的方式赋值
*
* 以上操作的先后顺序:① -> ② -> ③ -> ④
*/
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);

User u1 = new User(2);//构造器赋值
u1.age = 18;
System.out.println(u1.age);
}
}


class User{
String name;
int age = 1;//显式赋值

public User() {
//空参构造器
}
public User(int a) {
age = a;
}
}

扩展知识

扩展知识一:JavaBean

  1. JavaBean是一种Java语言写成的可重用组件。
  2. 所谓JavaBean,是指符合如下标准的Java类:
    • 类是公共的
    • 有一个无参的公共的构造器
    • 有属性,且有对应的get、set方法
  3. 用户可以使用JavaBean将功能、处理。值、数据库访问和其他任何可以用Java代码创造的对象进行打包,并且其他开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。

扩展知识二:UML类图

  1. +表示public类型,-表示private类型,#表示protected类型。

  2. 方法的写法:

    方法的类型(+、-) 方法名(参数名:参数类型):返回值类型

关键字:this

this关键字的使用

  1. this可以用来修饰:属性、方法、构造器。

  2. this修饰属性和方法:this可理解为当前对象(方法中)或当前正在创建的对象(构造器中)

    • 在类的方法中,我们可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象属性或方法。但是通常情况下,我们都选择省略“this.”。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式地使用“this.变量”的方式,表明此变量是属性,而非形参。
    • 在类的构造器中,我们可以使用“this.属性”或”this.方法“的方式,调用当前属性或方法。但是通常情况下,我们都选择省略”this.“。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式地使用“this.变量”的方式,表明此变量是属性,而非形参。、
  3. this调用构造器

    • 我们在类的构造器中,可以显式的使用“this(形参列表)”的方式,调用本类中指定的其他构造器。
    • 构造器中不能通过“this(形参列表)”的方式调用自己。
    • 如果有n个构造器,最多有n-1个个构造器中使用了“this(形参列表)”
    • 规定:“this(形参列表)”必须声明在当前构造器的首行
    • 构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他构造器。
  4. 示例

    package top.triabin.keywordthis;
    /**
    *
    * @Description this关键字的使用
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-8 19:47:08
    *
    */
    public class PersonTest {
    public static void main(String[] args) {
    Person p1 = new Person();
    p1.setAge(18);
    System.out.println(p1.getAge());

    Person p2 = new Person("Triabin",20);
    System.out.println(p2.getAge() + "\t" + p2.getName());
    }
    }


    class Person{
    private String name;
    private int age;


    public Person() {

    }
    //构造器中使用:理解为当前正在创建的对象(Person)
    public Person(String name) {
    this.name = name;
    }
    public Person(int age) {
    this.age = age;
    }
    public Person(String name,int age) {
    // this(name);//调用其他构造器
    // this.age = age;
    this(name);
    this.age = age;
    }


    //方法中使用:理解为当前对象(Person)
    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;
    }
    }

练习

练习一:添加必要的构造器,综合应用构造器的重载、this关键字。

Boy Girl
-name:String
-age:int
-name:String
-age:int
+setName(i:String)
+getName():String
+setAge(i:int)
+getAge():int
+marry(girl:Girl)
+shout():void
+setName(i:String)
+getName():String
+marry(boy:Boy)
+compare(girl:Girl)
  • Boy类
package top.triabin.keywordthis;

public class Boy {
private String name;
private int age;


public Boy() {
}
public Boy(String name, int age) {
this.name = name;
this.age = age;
}
public void marry(Girl girl) {
System.out.println("我想娶" + girl.getName());
}
public void shoult(){
if(this.age >= 22) {
System.out.println("你可以去登记结婚了!");
}else {
System.out.println("先多谈谈恋爱~~");
}
}


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;
}
}
  • Girl类
package top.triabin.keywordthis;

public class Girl {
private String name;
private int age;


public Girl() {
}
public Girl(String name, int age) {
this.name = name;
this.age = age;
}


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 void marry(Boy boy) {
System.out.println("我想嫁给" + boy.getName());
boy.marry(this);//this代表当前对象,即谁调用上面这个marry()方法谁就是这个this
}
/**
*
* @Description 比较两个对象大小
* @author Dawn Lee
* @version 1.0
* @data 2020-8-821:34:11
*
* @param girl
* @return 正数:当前对象大。 负数:当前对象小。 0:当前对象与形参对象相等
*/
public int comapre(Girl girl) {
return this.age - girl.age;
}
}
  • 测试类
package top.triabin.keywordthis;

public class ThisEx01 {
public static void main(String[] args) {
Boy boy = new Boy("罗密欧",23);
boy.shoult();

Girl girl = new Girl("朱丽叶",18);
girl.marry(boy);

Girl girl1 = new Girl("祝英台",20);
int compare = girl.comapre(girl1);
if(compare > 0) {
System.out.println(girl.getName() + "大");
}else if(compare == 0) {
System.out.println(girl.getName() + "和" + girl1.getName() + "一样大");
}else {
System.out.println(girl1.getName() + "大");
}
}
}
  • 运行

练习二:实验一

  1. 写一个名为 Account 的类模拟账户。该类的属性和方法如下图所示。该类包括的属性:
    账号 id,余 额 balance,年利率 annualInterestRate;包含的方法:访问器方法(getter 和 setter
    方法),取款方法 withdraw(),存款方法 deposit()。

    Account
    private int id
    private double balance
    private double annualInterestRate
    public Account (int id, double balance, double annualInterestRate )
    public int getId()
    public double getBalance()
    public double getAnnualInterestRate()
    public void setId( int id)
    public void setBalance(double balance)
    public void setAnnualInterestRate(double annualInterestRate)
    public void withdraw (double amount)//取钱
    public void deposit (double amount)//存钱
    • 提示:在提款方法 withdraw 中,需要判断用户余额是否能够满足提款数额的要求,如果不
      能,应给出提示。
    package top.triabin.keywordthis;
    /**
    *
    * @Description 实验一类:Account
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-9 9:48:18
    *
    */
    public class Account {
    private int id;//账号
    private double balance;//余额
    private double annualInterestRate;//年利率


    public Account(int id,double balance,double annualInterestRate) {
    this.id = id;
    this.balance = balance;
    this.annualInterestRate = annualInterestRate;
    }


    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public double getBalance() {
    return balance;
    }
    public void setBalance(double balance) {
    this.balance = balance;
    }
    public double getAnnualInterestRate() {
    return annualInterestRate;
    }
    public void setAnnualInterestRate(double annualInterestRate) {
    this.annualInterestRate = annualInterestRate;
    }
    public void withDraw(double amount) {//取钱
    if(amount > this.balance) {
    System.out.println("余额不足,取款失败!");
    return;
    }
    this.balance -= amount;
    System.out.println("成功取出:" + amount);
    }
    public void deposit(double amount) {//存钱
    this.balance += amount;
    System.out.println("成功存入:" + amount);
    }
    }
  2. 创建Customer类。

    Customer
    private String firstName
    private String lastName
    private Account account
    public Customer(String f,String l)
    public String getFirstName()
    public String getLastName()
    public Account getAccount()
    public void setAccount(Account account)
    • 声明三个私有对象属性:firstName、lastName 和 account。
    • 声明一个公有构造器,这个构造器带有两个代表对象属性的参数(f和 l)。
    • 声明两个公有存取器来访问该对象属性,方法getFirstName 和getLastName返回相应的属性。
    • 声明 setAccount 方法来对 account 属性赋值。
    • 声明 getAccount 方法以获取 account 属性。
    package top.triabin.keywordthis;
    /**
    *
    * @Description 实验一类:Customer
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-9 9:49:58
    *
    */
    class Customer{
    private String firstName;
    private String lastName;
    private Account account;


    public Customer(String f,String l) {
    this.firstName = f;
    this.lastName = l;
    }


    public String getFirstName() {
    return firstName;
    }
    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    public String getLastName() {
    return lastName;
    }
    public void setLastName(String lastName) {
    this.lastName = lastName;
    }

    public Account getAccount() {
    return account;
    }
    public void setAccount(Account account) {
    this.account = account;
    }
    }
  3. 写一个测试程序。

    (1)创建一个Customer,名字叫Jane Smith,他有一个账号为1000,余额为 2000 元,年利率为1.23%的账户。

    (2)对Jane Smith操作。

    • 存入100元,再取出960元。再取出2000元。
    • 打印出Jane Smith的基本信息。
    package top.triabin.keywordthis;
    /**
    *
    * @Description 课后练习:实验一
    * @author DawnLee
    * @version 1.0
    * @data 2020-8-9 9:45:58
    *
    */
    public class Experiment1Test {
    public static void main(String[] args) {
    Customer c = new Customer("Jane","Smith");
    Account a = new Account(1000,2000,1.23);
    a.deposit(100);
    a.withDraw(960);
    a.withDraw(2000);
    System.out.println("Custmor [" + c.getFirstName() + "·" + c.getLastName() + "] has a account: id is " + a.getId() + ", \nannualInterestRate is " + a.getAnnualInterestRate() + "%, balance is " + a.getBalance());
    }
    }
    • 运行

练习三:实验二

  1. 按照如下的UML类图,创建相应的类,提供必要的的结构。

    Account
    -balance:double
    +Account(init_balance:double)
    +getBalance():double
    +deposit(amt:double)
    +withdraw(amt:double)

    在提款方法withdraw()中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应该给出提示。deposit()方法表示存款。

    package experiment2;
    /**
    *
    * @Description this关键字课后练习:实验二类1--Account
    * 初始化账户余额和存取钱
    * @author DawnLee
    * @version
    * @data 2020-8-9 14:16:23
    *
    */
    public class Account {
    private double balance;


    public Account(double init_balance) {
    balance = init_balance;
    }


    public double getBalance() {
    return balance;
    }
    public void deposit(double amt) {//存钱
    if(amt > 0) {
    balance += amt;
    System.out.println("\n成功存入:" + amt + "元。\n当前余额:" + balance + "元。");
    }
    }
    public void withdraw(double amt) {
    if(amt > balance) {
    System.out.println("\n余额不足,取款失败!\n当前余额:" + balance + "元。");
    return;
    }
    balance -= amt;
    System.out.println("成功取出:" + amt + "元。\n当前余额:" + balance + "元。");
    }
    }
  2. 按照如下的UML类图,创建相应的类,提供必要的结构。

    Customer
    -firstName:String
    -lastName:String
    -account:Account
    +Customer(f:String,l:String)
    +getFirstName():String
    +getLastName():String
    +getAccount():Account
    +setAccount(account:Account)
    package experiment2;
    /**
    *
    * @Description this关键字课后练习:实验二类2--Customer
    * 新建账户的账户名,以及查询账户等操作
    * @author DawnLee
    * @version
    * @data 2020-8-9 14:27:17
    *
    */
    public class Customer {
    private String firstName;
    private String lastName;
    private Account account;


    public Customer(String f,String l) {
    firstName = f;
    lastName = l;
    }


    public Account getAccount() {
    return account;
    }
    public void setAccount(Account account) {
    this.account = account;
    }
    public String getFirstName() {
    return firstName;
    }
    public String getLastName() {
    return lastName;
    }
    }
  3. 按照如下的UML类图,创建相应的类,提供必要的结构。

    Bank
    -customers:Customer[]
    -numberOfCustomer:int
    +Bank()
    +addCustomer(f:string,l:String)
    +getNumOfCustomer():int
    +getCustomer(index:int):Customer
    • addCustomer()方法必须依照参数(姓,名)构造一个新的Customer对象,然后把它放到customer数组中。还必须吧numberOfCustomer属性的值加1.
    • getNumOfCustomer()方法返回numberOfCustomer属性值。
    • getCustomer()方法返回与给出的index参数相关的客户。
    package experiment2;
    /**
    *
    * @Description this关键字课后练习:实验二类3--Bank
    * 新建用户并计数,将账户信息存入数组
    * @author DawnLee
    * @version
    * @data 2020-8-9 14:31:13
    *
    */
    public class Bank {
    private Customer[] customers = new Customer[10];
    private int numberOfCustomer;


    public Bank() {
    //空参构造器
    }


    public void addCustomer(String f,String l) {
    Customer customer = new Customer(f,l);
    customers[numberOfCustomer++] = customer;
    }
    public int getNumOfCustomer() {
    return numberOfCustomer;
    }
    public Customer getCustomer(int index) {
    // return customers[index];//可能报异常
    if(index >= 0 && index < numberOfCustomer) {
    return customers[index];
    }
    return null;
    }
    }
  4. 创建BankTest类,进行测试。

    package experiment2;
    /**
    *
    * @Description this关键字课后练习:实验二类4--测试类
    * 测试各功能的使用
    * @author DawnLee
    * @version
    * @data 2020-8-9 16:07:49
    *
    */
    public class BankTest {
    public static void main(String[] args) {
    Bank bank = new Bank();
    bank.addCustomer("Dawn", "Lee");
    bank.getCustomer(0).setAccount(new Account(2000));
    bank.getCustomer(0).getAccount().withdraw(500);
    System.out.println("账户名:" + bank.getCustomer(0).getFirstName() +bank.getCustomer(0).getLastName());

    bank.addCustomer("Triabin", "Lee");
    System.out.println("\n当前银行客户数量为:" + bank.getNumOfCustomer());
    }
    }
    • 运行

关键字:package、import

package

package关键字的使用

  1. 为了更好的实现项目中类的管理,提供包的概念。
  2. 使用package来声明类或接口所属的包,声明在源文件首行。
  3. 包,属于标识符,遵循标识符的命名规则、规范(全小写)、见名知意。
  4. 每“.”一次,就代表一层文件目录。

补充:同一个包下,不能命名同名的接口、类。

JDK中主要的包介绍

  1. java.lang—-包含一些Java语言的核心类,如String、Math、Integer、 System和
    Thread,提供常用功能。
  2. java.net—-包含执行与网络相关的操作的类和接口。
  3. java.io—-包含能提供多种输入/输出功能的类。
  4. java.util—-包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。
  5. java.text—-包含了Java进行JDBC数据库编程的相关类/接口。
  6. java.sql—-包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。

MVC设计模式

  • MVC是常用的设计模式之一,将整个程序分为三个层次:视图模型层,控制器层,与

    数据模型层。这种将程序输入输出、数据处理,以及数据的展示分离开来的设计模式

    使程序结构变的灵活而且清晰,同时也描述了程序各个对象间的通信方式,降低了程

    序的耦合性。

  1. 模型层:model,主要处理数据。
    • 数据对象封装 model.bean/domain
    • 数据库操作类 model.dao
    • 数据库 model.db
  2. 控制层:controller,处理业务逻辑。
    • 应用界面相关 controller.activity
    • 存放fragment controller.fragment
    • 显示列表的适配器 controller.adapter
    • 服务相关的 controller.service
    • 抽取的基类 controller.base
  3. 视图层:view,显示数据。
    • 相关工具类 view.utils
    • 自定义view view.ui
  • 包(package)能使整个结构变得清晰

import

import关键字的使用

  1. 在源文件显式的使用import结构导入指定包下的类、接口。

  2. 声明在包的声明和类的声明之间。

  3. 如果需要导入多个包,则并列写出即可。

  4. 可以使用“xxx.*”的方式导入xxx包下所有结构。

  5. 如果使用的类或接口是java.lang包下定义的,则可以省略import结构。

  6. 如果使用的类或接口是本包下定义的,则可以省略import结构。

  7. 如果再源文件中使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。

  8. 如果使用“xxx.*”的方式表明可以调用xxx包下所有结构。但如果使用的是xxx子包下的结构,仍需要显示导入。

  9. import static:导入指定类或接口中的静态结构。

    静态结构:属性或方法

章节练习题及面试题

类的实例化

代码实现

编写一个Student类,包含name、gender、age、id、score属性,分别为String、String、int、int、double类型。

类中声明一个say方法,返回String类型,方法返回信息中包含所有属性值。

package top.triabin._01;
/**
*
* @Description 编写一个Student类,包含name、gender、age、id、score属性,分别为String、String、
* int、int、double类型。
* 类中声明一个say方法,返回String类型,方法返回信息中包含所有属性值。
* @author DawnLee
*
* @version 1.0
* @data 2020-9-30 8:47:59
*
*/
public class Student {
private String name;
private String gender;
private int age;
private int id;
private double score;

public Student(String name,String gender,int age,int id,double score) {
this.name = name;
this.gender = gender;
this.age = age;
this.id = id;
this.score = score;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String say() {
return "naem: " + this.name + "\ngender: " + gender + "\nage: " + age + "\nid: " + id + "\nscore: " + score;
}
}

在另一个StudentTest类中的main方法中,创建Student对象,并访问say方法和所有属性,并将调用结果打印输出。

package top.triabin._01;
/**
*
* @Description 在另一个StudentTest类中的main方法中,创建Student对象,并访问say方法和所有属性,
* 并将调用结果打印输出。
* @author DawnLee
* @version 1.0
* @data 2020-9-30 9:55:28
*
*/
public class StudentTest {
public static void main(String[] args) {
Student stu = new Student("Triabin","男",18,1001,99.9999);
System.out.println("调用属性:");
System.out.println("name: " + stu.getName());
System.out.println("gender: " + stu.getGender());
System.out.println("age: " + stu.getAge());
System.out.println("id: " + stu.getId());
System.out.println("score: " + stu.getScore());
System.out.println();

System.out.println("调用say()方法:");
System.out.println(stu.say());
}
}
  • 运行结果

编程题1

定义一个丈夫Husband类,有姓名、年龄、妻子属性;

定义一个妻子Wife类,有姓名、年龄、丈夫属性。

丈夫类中有一个getInfo()方法,其中能显示自己的姓名、年龄和他妻子的姓名、年龄;

package top.triabin._02;
/**
*
* @Description 定义一个丈夫Husband类,有姓名、年龄、妻子属性;
* 丈夫类中有一个getInfo()方法,其中能显示自己的姓名、年龄和他妻子的姓名、年龄;
* @author DawnLee
* @version 1.0
* @data 2020-9-30 10:11:23
*
*/
public class Husband {
private String name;
private int age;
private Wife wife;

public Husband() {
//空参构造器
}
public Husband(String name,int age,Wife wife) {
this.name = name;
this.age = age;
this.wife = wife;
}

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 Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
public void getInfo() {
System.out.println("姓名:" + this.name);
System.out.println("年龄:" + this.age);
System.out.println("妻子:");
System.out.println(" 姓名:" + this.wife.getName());
System.out.println(" 年龄:" + this.wife.getAge());
}
}

妻子类中有一个getInfo()方法,能显示自己的姓名、年龄和她丈夫的姓名、年龄。

package top.triabin._02;
/**
*
* @Description 定义一个妻子Wife类,有姓名、年龄、丈夫属性。
* @author DawnLee
* @version 1.0
* @data 2020-9-30 10:13:25
*
*/
public class Wife {
private String name;
private int age;
private Husband husband;

public Wife() {
//空参构造器
}
public Wife(String name,int age,Husband husband) {
this.name = name;
this.age = age;
this.husband = husband;
}

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 Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
public void getInfo() {
System.out.println("姓名:" + this.name);
System.out.println("年龄:" + this.age);
System.out.println("丈夫:");
System.out.println(" 姓名:" + this.husband.getName());
System.out.println(" 年龄:" + this.husband.getAge());
}
}

定义一个测试类,创建妻子和丈夫对象,然后测试。

package top.triabin._02;
/**
*
* @Description 定义一个妻子Wife类,有姓名、年龄、丈夫属性。
* @author DawnLee
* @version 1.0
* @data 2020-9-30 10:13:25
*
*/
public class Wife {
private String name;
private int age;
private Husband husband;

public Wife() {
//空参构造器
}
public Wife(String name,int age,Husband husband) {
this.name = name;
this.age = age;
this.husband = husband;
}

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 Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
public void getInfo() {
System.out.println("姓名:" + this.name);
System.out.println("年龄:" + this.age);
System.out.println("丈夫:");
System.out.println(" 姓名:" + this.husband.getName());
System.out.println(" 年龄:" + this.husband.getAge());
}
}
  • 运行结果

编程题2

定义银行账户类Account,有属性:卡号cid,余额balance,所属用户Customer,银行账户类Account有方法:

  • getInfo(),返回String类型,返回卡的详细信息;
  • 取钱方法withdraw(),参数自行设计,如果取钱成功,返回true,失败返回false;
  • 存钱方法save(),参数自行设计,如果存钱成功,返回true,失败返回false。
package top.triabin._03;
/**
*
* @Description 定义银行账户类Account,有属性:卡号cid,余额balance,所属用户Customer,银行账户类
* Account有方法:
* getInfo(),返回String类型,返回卡的详细信息;
* 取钱方法withdraw(),参数自行设计,如果取钱成功,返回true,失败返回false;
* 存钱方法save(),参数自行设计,如果存钱成功,返回true,失败返回false。
* @author DawnLee
* @version 1.0
* @data 2020-9-30 10:50:33
*
*/
public class Account {
private int cid;
private double balance;
private Customer customer;

public Account() {
//空参构造器
}
public Account(int cid,double balance,Customer customer) {
this.cid = cid;
this.balance = balance;
this.customer = customer;
}

public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public String getInfo() {
return "卡号:" + getCid() + "\n余额:" + getBalance() + "\n" + customer.say();
}
public boolean withdraw(double money) {
if(money <= this.balance && money > 0) {
this.balance -= money;
return true;
}else if(money > 0){
return false;
}
System.out.println("输入错误,请输入大于0的数字。");
return false;
}
public boolean save(double money) {
if(money > 0) {
this.balance += money;
return true;
}
System.out.println("输入错误,请输入大于0的数字。");
return false;
}
}

其中,Customer类有姓名、身份证号、联系电话、家庭住址等属性。Customer类有方法say(),返回String类型,返回他的个人信息。

package top.triabin._03;
/**
*
* @Description 其中,Customer类有姓名、身份证号、联系电话、家庭住址等属性。Customer类有方法say(),
* 返回String类型,返回他的个人信息。
* @author DawnLee
* @version 1.0
* @data 2020-9-30 10:53:52
*
*/
public class Customer {
private String name;
private int id;
private String tele;
private String address;

public Customer() {
super();
}
public Customer(String name, int id, String tele, String address) {
super();
this.name = name;
this.id = id;
this.tele = tele;
this.address = address;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTele() {
return tele;
}
public void setTele(String tele) {
this.tele = tele;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String say() {
return "姓名:" + this.name + "\n身份证号:" + this.id + "\n联系电话:" + this.tele + "\n家庭住址:" + this.address;
}
}

在测试类Bank中创建银行账户类对象和用户类对象,并设置信息与显示信息。

package top.triabin._03;
/**
*
* @Description 在测试类Bank中创建银行账户类对象和用户类对象,并设置信息与显示信息。
* @author DawnLee
* @version 1.0
* @data 2020-9-30 10:54:37
*
*/
public class Bank {
public static void main(String[] args) {
Customer customer = new Customer("Triabin",5201314,"18222222222","月宫");
Account account = new Account(1001,5000,customer);

System.out.println(account.getInfo());
if(account.withdraw(200)) {
System.out.println("取款成功,余额:" + account.getBalance());
}else {
System.out.println("取款失败。");
}
if(account.save(250)) {
System.out.println("存款成功,余额:" + account.getBalance());
}
}
}
  • 运行结果

方法的使用

哪个选项和show()方法重载?

class Demo{
void show(int a,int b,float c){}
}

A.void show(int a,float c,int b){}//yes

B,void show(int a,int b,float c){}//一模一样。不可以出现在同一个类中。

C.int show(int a,float c,int b){return a;}//yes。

D.int show(int a,float c){return a;}//yes

方法的声明与调用

  1. 声明一个圆柱体类;

  2. 声明属性:底边的半径,和高;

  3. 声明方法:

    • 方法的功能:在方法中打印圆柱体的详细信息

      圆柱体的底边的半径是xxx,高是xxx,底面积是xxx,体积是xxx。

    • 方法的功能:返回底面积

    • 方法的功能:返回体积

    • 方法的功能:为圆柱体的底边的半径,和高赋值

    • 方法的功能:为圆柱体的底边的半径,和高赋值,并返回赋值的结果,如果底边的半径或高为<=0,赋值失败,返回false,否则返回true

    package top.triabin._04;

    public class Cylinder {
    private double radius;
    private double height;
    public Cylinder() {
    super();
    }
    public Cylinder(double radius, double height) {
    super();
    this.radius = radius;
    this.height = height;
    }

    public double getRadius() {
    return radius;
    }
    public void setRadius(double radius) {
    this.radius = radius;
    }
    public double getHeight() {
    return height;
    }
    public void setHeight(double height) {
    this.height = height;
    }
    /**
    * 方法功能:返回底面积
    */
    public double getBasalArea() {
    return this.radius * this.radius * Math.PI;
    }
    /**
    * 方法的功能:返回体积
    */
    public double getVolume() {
    return getBasalArea() * this.height;
    }
    /**
    * 方法的功能:为圆柱体的底边的半径,和高赋值
    */
    public void setRadiusHeight(double radius,double height) {
    this.radius = radius;
    this.height = height;
    }
    /**
    * 方法的功能:为圆柱体的底边的半径,和高赋值,并返回赋值的结果,如果底边的半径或高为<=0,
    * 赋值失败,返回false,否则返回true
    */
    public boolean setRH(double radius,double height) {
    if(radius <= 0 || height <= 0) {
    return false;
    }else {
    this.radius = radius;
    this.height = height;
    System.out.println("radius = " + this.radius + "\nheight = " + this.height);
    return true;
    }
    }
    /**
    * 方法的功能:在方法中打印圆柱体的详细信息
    * 圆柱体的底边的半径是xxx,高是xxx,底面积是xxx,体积是xxx。
    *
    */
    public void pointInfo() {
    System.out.println("圆柱的底边半径是" + this.radius + ",高是" + this.height + ",底面积是" + getBasalArea() + ",体积是" + getVolume() + "。");
    }
    }
  4. 测试

    package top.triabin._04;

    public class Test {
    public static void main(String[] args) {
    Cylinder cylinder = new Cylinder(10,5);
    System.out.println("测试1:");
    cylinder.pointInfo();
    System.out.println();

    System.out.println("测试2:");
    cylinder.setRadiusHeight(100, 10);
    cylinder.pointInfo();
    System.out.println();

    System.out.println("测试3:");
    boolean isDone = cylinder.setRH(50, 10);
    System.out.println(isDone);
    System.out.println("失败测试:");
    isDone = cylinder.setRH(-100, 0);
    System.out.println(isDone);
    }
    }
  • 运行结果

方法的重载

方法重载(overload)必须满足____

A. 在不同class中定义的方法 B.在同一类型中定义的方法

C. 方法名必须相同 D.返回类型必须相同

E. 参数一定不同 F.参数可以相同

答案:BCE

写出输出结果

class Demo{
public static void main(String[] args){
show(0);
show(1);
}
public static void show(int i){
switch(i){
default:
i+=2;
case 1:
i+=1;
case 4:
i+=8;
case 2:
i+=4;
}
System.out.println("i="+i);
}
}

输出结果:

i=15

i=14

写出输出结果

class Demo{
public static void main(String[] args){
int x = 1;
for(show('a'); show('b') && x<3; show('c')){
show('d');
x++;
}
}
public static boolean show(char ch){
System.out.print(ch);
return true;
}
}

输出结果:

abdcbdcb

以下代码的运行结果是什么?

public class Test1 {
public static boolean foo(char c) {
System.out.print(c);
return true;
}

public static void main(String[] args) {
int i = 0;
for (foo('A'); foo('B') && (i < 2); foo('C')) {
i++;// 1 2
foo('D');
}
}
}

答案:ABDCBDCB

面向对象

面向对象的三大特征说明

答:面向对象有三大特点:封装、继承、多态。(如果要回答四个,可加上抽象性这一特点)

  1. 继承性

    继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。

  2. 封装性

    封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

  3. 多态性

    多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

  4. 抽象性

    抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

作用域public、private、protected及默认不写时的区别?

  1. public:修饰的结构在同一个工程(Project)中的结构都可调用;
  2. protected:同一个工程中不同包的子类、同一个包以内都可调用;
  3. 不写(缺省):同一个包中的结构都可调用;
  4. private:只在其所在类内部可以调用。

找错

public class Something {
void doSomething () {
private String s = "";
int l = s.length();
}
}

答案:错。局部变量前不能放置任何访问修饰符 (private,public,和protected)。

Java的内存管理之垃圾回收(了解)

分配:由JVM自动为其分配相应的内存空间

释放:由JVM提供垃圾回收机制自动的释放内存空间

垃圾回收机制(GC:Garbage Collection):将垃圾对象所占用的堆内存进行回收。Java的垃圾回收机制是JVM提供的能力,由单独的系统级垃圾回收线程在空闲时间以不定时的方式动态回收。

**垃圾对象**:不再被任何引用指向的对象。

面试题:

问:在程序中是否可以通知垃圾回收机制过来回收垃圾?

​ 能,通过调用System.gc();或Runtime.getRuntime().gc();

再问:调用了System.gc();或Runtime.getRuntime().gc();后是立刻执行垃圾回收吗?

​ 不是,该调用并不会立刻启动垃圾回收机制开始回收,但会加快垃圾回收机制的运行。

public class TestGC{
public static void main(String[] args)throws Exception{
for(int i=0; i<10; i++){
MyClass m = new MyClass();//这里本次循环完,本次创建的对象就成为垃圾了
System.out.println("创建第" + (i+1) + "的对象:" + m);
}

//通知垃圾回收机制来收集垃圾
System.gc();

//为了延缓程序结束
for(int i=0; i<10; i++){
Thread.sleep(1);
System.out.println("程序在继续....");
}
}
}
class MyClass{
//这个方法是垃圾回收机制在回收它的对象时,自动调用,理解成对象留临终遗言的方法
public void finalize(){
System.out.println("轻轻的我走了.....");
}
}

构造器

构造器Constructor是否可以被Override?

答:构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。

编程创建一个Box类,在其中定义三个变量表示立方体的长、宽和高,定义一个方法求立方体的体积。创建一个对象,求给定尺寸的立方体的体积。

(提供无参的构造器和一个有参的构造器)

package top.triabin._05;
/**
*
* @Description 编程创建一个Box类,在其中定义三个变量表示立方体的长、宽和高,定义一个方法求立方体
* 的体积。创建一个对象,求给定尺寸的立方体的体积。
* (提供无参的构造器和一个有参的构造器)
* @author DawnLee
* @version 1.0
* @data 2020-9-30 13:18:23
*
*/
public class BoxTest {
public static void main(String[] args) {
Box box = new Box(10,20,30);
System.out.println("立方体参数:");
System.out.println("长 = " + box.getLegth());
System.out.println("宽 = " + box.getWidth());
System.out.println("高 = " + box.getHeight());
System.out.println("体积 = " + box.getVolume());
}
}
class Box{
private int legth;
private int width;
private int height;

public Box() {
super();
}
public Box(int legth, int width, int height) {
super();
this.legth = legth;
this.width = width;
this.height = height;
}

public int getLegth() {
return legth;
}
public void setLegth(int legth) {
this.legth = legth;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getVolume() {
return this.legth * this.height * this.width;
}
}
  • 运行结果

定义一个圆类型

  • 提供显示圆周长功能的方法
  • 提供显示圆面积的方法
  • 提供无参的构造器和一个有参的构造器
package top.triabin._06;
/**
*
* @Description 定义一个圆类型
* 提供显示圆周长的方法
* 提供显示圆面积的方法
* 提供无参和有参构造器
* @author DawnLee
* @version 1.0
* @data 2020-9-30 13:38:30
*
*/
public class Circle {
private double radius;

public Circle() {
super();
}
public Circle(double radius) {
super();
this.radius = radius;
}

public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public void showCir() {
System.out.println("周长 = " + (2 * Math.PI * this.radius));
}
public void showArea() {
System.out.println("面积 = " + (Math.PI * this.radius * this.radius));
}
}

设计一个Dog类,有名字、颜色和年龄属性,定义构造器初始化这些属性,定义输出方法show()显示其信息。

(提供无参的构造器和一个有参的构造器)

package top.triabin._07;
/**
*
* @Description 设计一个Dog类,有名字、颜色和年龄属性,定义构造器初始化这些属性,定义输出方法
* show()显示其信息。
* (提供无参的构造器和一个有参的构造器)
* @author DawnLee
* @version 1.0
* @data 2020-9-30 13:45:53
*
*/
public class DogTest{
public static void main(String[] args) {
new Dog("MH","brown",12).show();
}
}
class Dog {
private String name;
private String color;
private int age;

public Dog() {
super();
}
public Dog(String name, String color, int age) {
super();
this.name = name;
this.color = color;
this.age = age;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println("name: " + this.name + "\ncolor: " + this.color + "\nage: " + this.age);
}
}
  • 运行结果

定义一个类,用于描述坐标点

o——————>X

|

|

|

Y P(X,Y)

  1. 具有计算当前点到原点距离的功能
  2. 求到任意一点(m,n)的距离
  3. 求到任意一点(Point p)的距离
  4. 具有坐标点显示功能,显示格式(x,y)
  5. 提供无参的构造器和一个有参的构造器
package top.triabin._08;

public class PointTest {
public static void main(String[] args) {
Point p1 = new Point(4,3);
Point p2 = new Point(8,6);

System.out.println("当前点到原点的距离 = " + p1.getLenToOrigin());
System.out.println("到(12,9)的距离 = " + p1.getLenAny(12, 9));
System.out.println("到(Point p2)的距离 = " + p1.getLenAny(p2));
System.out.println("显示坐标:");
p1.showPoint();
p2.showPoint();
}
}

class Point{
private int x;
private int y;

public Point() {
super();
}
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}

public double getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
/**
* 具有计算当前点到原点距离的功能
*/
public double getLenToOrigin() {
return Math.sqrt(this.x*this.x + this.y*this.y);
}
/**
* 求到任意一点(m,n)的距离
*/
public double getLenAny(double m,double n) {
return Math.sqrt(Math.pow((this.x - m), 2) + Math.pow((this.y - n), 2));
}
/**
* 求到任意一点(Point p)的距离
*/
public double getLenAny(Point p) {
return Math.sqrt(Math.pow((this.x - p.getX()), 2) + Math.pow((this.y - p.getY()), 2));
}
/**
* 具有坐标点显示功能,显示格式(x,y)
*/
public void showPoint() {
System.out.println("(" + this.x + "," + this.y + ")");
}
}
  • 运行结果

写一个人的类

属性:名字,性别,年龄;提供无参的构造器和一个有参的构造器

方法:①自我介绍的方法 ②吃饭的方法

创建一个对象“张三”

package top.triabin._09;
/**
*
* @Description 属性:名字,性别,年龄;提供无参的构造器和一个有参的构造器
* @author DawnLee
* @version 1.0
* @data 2020-9-30 14:27:07
*
*/
public class Person {
public static void main(String[] args) {
Person zhangSan = new Person("张三","男",32);
zhangSan.selfIntro();
zhangSan.eat();
}

private String name;
private String gender;
private int age;

public Person() {
super();
}
public Person(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void selfIntro() {
System.out.println("大家好,我叫" + this.name);
}
public void eat() {
System.out.println("吃饭");
}
}
  • 运行结果

写一个汽车类

属性:品牌、车长、颜色、价格;

package top.triabin._10;
/**
*
* @Description 属性:品牌、车长、颜色、价格;
* 提供无参的构造器和一个有参的构造器
* @author DawnLee
* @version 1.0
* @data 2020-9-30 14:36:46
*
*/
public class Car {
private String brand;
private double length;
private String color;
private double price;

public Car() {
super();
}
public Car(String brand, double length, String color, double price) {
super();
this.brand = brand;
this.length = length;
this.color = color;
this.price = price;
}

public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}

创建五个对象:“捷达”,“宝马”,“劳斯莱斯”,“科鲁兹”,“迈锐宝”

提供无参的构造器和一个有参的构造器

package top.triabin._10;
/**
*
* @Description 创建五个对象:“捷达”,“宝马”,“劳斯莱斯”,“科鲁兹”,“迈锐宝”
* @author DawnLee
* @version 1.0
* @data 2020-9-30 14:41:11
*
*/
public class CarTest {
@SuppressWarnings("unused")
public static void main(String[] args) {
Car c1 = new Car("捷达",4.415,"棕色",200000);
Car c2 = new Car("宝马",5.055,"白色",300000);
Car c3 = new Car("劳斯莱斯",5.770,"蓝色",1500000);
Car c4 = new Car("科鲁兹",4.643,"灰色",120000);
Car c5 = new Car("迈锐宝",4.855,"银色",150000);
}
}

写一个课程类

属性:课程名;学时;任课老师;

package top.triabin._11;
/**
*
* @Description 写一个课程类
* 属性:课程名;学时;任课老师;
* @author DawnLee
* @version 1.0
* @data 2020-10-1 13:34:19
*
*/
public class Course {
private String courseName;
private double time;
private String teacher;

public Course() {
super();
}
public Course(String courseName, double time, String teacher) {
super();
this.courseName = courseName;
this.time = time;
this.teacher = teacher;
}

public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public double getTime() {
return time;
}
public void setTime(double time) {
this.time = time;
}
public String getTeacher() {
return teacher;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
}

创建五个对象:“c语言”,“java编程”,“php网络编程”,“c++”,“数据结构”

提供无参的构造器和一个有参的构造器

package top.triabin._11;
/**
*
* @Description 创建五个对象:“c语言”,“java编程”,“php网络编程”,“c++”,“数据结构”
* @author DawnLee
* @version 1.0
* @data 2020-10-1 13:37:31
*
*/
public class CourseTest {
@SuppressWarnings("unused")
public static void main(String[] args) {
Course course1 = new Course("c语言",64,"A老师");
Course course2 = new Course("java编程",48,"B老师");
Course course3 = new Course("php网络编程",32,"C老师");
Course course4 = new Course("c++",64,"D老师");
Course course5 = new Course("数据结构",64,"E老师");
}
}

以下程序的运行结果是:

public class Test1 {
public static void main(String[] args) {
new A(new B());
}
}
class A{
public A(){
System.out.println("A");
}
public A(B b){
this();
System.out.println("AB");
}
}
class B{
public B(){
System.out.println("B");
}
}

答案:

B

A

AB

关于参数传递

练习一:写出结果

public class Test{ 
public static void leftShift(int i, int j){
i+=j;
}
public static void main(String args[]){
int i = 4, j = 2;
leftShift(i, j);
System.out.println(i);
}
}

答案:4。和leftShift()方法没关系。

练习二:写出结果

public class Demo{ 
public static void main(String[] args){
int[] a=new int[1];
modify(a);
System.out.println(a[0]); //
}
public static void modify(int[] a){
a[0]++;
}
}

答案:1。

练习三

public class TestA {
int i ;
void change(int i){
i++;
System.out.println(i);
}
void change1(TestA t){
t.i++;
System.out.println(t.i);
}
public static void main(String[] args) {
TestA ta = new TestA();
System.out.println(ta.i); //0
ta.change(ta.i);//1
System.out.println(ta.i); //0
ta.change1(ta); //1
System.out.println(ta.i);//0
}
}

练习四:写出结果

class Value{
int i = 15;
}
class Test{
public static void main(String argv[]) {
Test t = new Test();
t.first();
}

public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);
}

public void second(Value v, int i) {
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.print(v.i + " " + i);
}
}

A.15 0 20

B.15 0 15

C.20 0 20

D.0 15 20

A is correct.

练习五

public class Test {
int x= 12;
public void method(int x) {
x+=x;
System.out.println(x);
}
}
Given:
34.Test t = new Test();
35.t.method(5);

What is the output from line 5 of the Test class?

A.5 B.10 C.12

D.17 E.14

练习六

import java.util.Arrays;

public class PassValueExer2{
public static void main(String[] args){
int[] array = {3,2,5,1,7};

//调用sort方法,实现从大到小排序
//在此处补充代码
....

//显示结果
System.out.println("排序后的结果是:" + Arrays.toString(array));
}

//要求使用冒泡排序完成
public void sort(//形参?){

}
}

答案:

/*
考点:
1、方法的参数传递机制
2、冒泡排序
*/
import java.util.Arrays;

public class PassValueExer2{
public static void main(String[] args){
int[] array = {3,2,5,1,7};
PassValueExer2 exer = new PassValueExer2();
//调用sort方法,实现排序
exer.sort(array);//实参给形参的是地址,数组的首地址

//遍历结果
System.out.println("排序后的结果是:" + Arrays.toString(array));
}

//功能:用冒泡排序,实现为数组排序,而且从大到小
//形参的类型?我要把什么传过来
//传递数组
//接收的类型也肯定是数组,即形参接收实参,即形参的类型是int[]
public void sort(int[] arr){
//冒泡排序
//在这里对谁排,对arr进行排序
for(int i=1; i<arr.length; i++){//多少轮
//每一轮,从左往后--》for(int j=0;...)
//要实现从大到小-->前面的元素比后面的元素小,就交换
//每一轮几次,
//假设,数组的长度为5
//第一轮:4次,i=1, j=0,1,2,3 j<4 j< arr.length-i
//第二轮:3次,i=2, j=0,1,2
for(int j=0; j<arr.length-i; j++){
if(arr[j] < arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
}

以下代码的执行结果是什么?

public static void main(String[] args) {
int i = 0;
change(i);
i = i++;
System.out.println("i = " + i);
}
public static void change(int i){
i++;
}

答案:i=0

以下程序的运行结果:

public static void main(String[] args) {
String str = new String("world");
char[] ch = new char[]{'h','e','l','l','o'};
change(str,ch);
System.out.println(str);
System.out.println(String.valueOf(ch));
}
public static void change(String str, char[] arr){
str = "change";
arr[0] = 'a';
arr[1] = 'b';
arr[2] = 'c';
arr[3] = 'd';
arr[4] = 'e';
}

答案:

world

abcde

以下代码的运行结果是?

public class Test {
int a;
int b;
public void f(){
a = 0;
b = 0;
int[] c = {0};
g(b,c);
System.out.println(a + " " + b + " " + c[0]);
}
public void g(int b, int[] c){
a = 1;
b = 1;
c[0] = 1;
}
public static void main(String[] args) {
Test t = new Test();
t.f();
}
}

答案:101

简答

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的

补足compare函数内的代码,不许添加其他函数。

class Circle {
private double radius;

public Circle(double r) {
radius = r;
}

public Circle compare(Circle cir) {
// 程序代码
/*
* if(this.radius>cir.radius) return this; return cir;
*/

// return (this.radius>cir.radius)?this: cir;

}
}

class TC {
public static void main(String[] args) {
Circle cir1 = new Circle(1.0);
Circle cir2 = new Circle(2.0);
Circle cir;
cir = cir1.compare(cir2);
if (cir1 == cir)
System.out.println("圆1的半径比较大");
else
System.out.println("圆2的半径比较大");
}
}

Eclipse快捷键的使用

  • Eclipse中快捷键的使用:
    • 补全代码的声明:Alt + /
    • 快速修复:Ctrl + 1
    • 批量导包:Ctrl + Shift + O
    • 单行注释:Ctrl + /
    • 多行注释:Ctrl + Shift + /
    • 取消多行注释:Ctrl + Shift + \
    • 复制指定行的代码:Ctrl + Alt + Down/Up
    • 删除指定行的代码:Ctrl + D
    • 上下移动代码:Alt + Up/Down
    • 向下插入空行:Shift + Enter
    • 向上插入空行:Ctrl + Shift + Enter
    • 如何查看源代码:Ctrl + 点击指定的结构 或 Ctrl + Shift + T
    • 退回到前一个编辑的页面:Alt + Left
    • 进入到下一个编辑的页面(针对于上面那条来说的):Alt + Right
    • 光标选中指定的类,查看继承树结构:Ctrl + T
    • 格式化代码:Ctrl + Shift + F
    • 选中行数整体后移:Tab
    • 选中行数整体前移:Shift + Tab
    • 在当前类中,显示类结构,并支持搜索指定的方法、属性等:Ctrl + O
    • 批量修改指定的变量名、方法名、类名等:Alt + Shift + R
    • 选中结构大小写切换–变成大写:Ctrl + Shift + X
    • 选中结构大小写切换–变成小写:Ctrl + Shift + Y
    • 调出生成getter/setter/构造器等结构:Alt + Shift + S
    • 显示当前选择资源(工程or文件)的属性:Alt + Enter
    • 快速查找–参照选中的word快速定位到下一个:Ctrl + K
    • 关闭当前窗口:Ctrl + W
    • 关闭所有窗口:Ctrl + Shift + W
    • 查看指定结构使用过的地方:Ctrl + Alt + G
    • 查找与替换:Ctrl + F
    • 最大化当前的View:Ctrl + M
    • 直接定位到当前的首位:Home
    • 直接定到当前的末位:End