JAVA入门——the fourth lesson

方法

语句块

语句块 (也叫复合语句) 。
语句块中定义的变量只能用于自己,外部不能使用。

//(即语句块可以使用外部的变量,而外部不能使用语句块的变量)
public class Test19 {
    public static void main(String[ ] args) {
        int n;
        int a;
        {
            int k;
            int n;//编译错误:  不能重复定义变量 n
        } //变量 k 的作用域到此为止
    }
}

方法

方法(method):一段用来完成特定功能的代码片段, 类似于其它语言的函数(function)。

方法用于定义该类或该类的实例的行为特征和功能实现。
面向过程中, 函数是最基本单位, 整个程序由一个个函数调用组成。

面向对象中, 整个程序的基本单位是类, 方法是从属于类和对象的。

方法的重载(overload)

重载: 一个类中可以定义多个名称相同, 但形式参数列表不同的方法。(重载的方法实际是完全不同的方法,只是名称相同而已)

构成方法重载的条件:

  1. 形参列表不同的含义: 形参类型、形参个数、形参顺序不同
  2. 只有返回值不同不构成方法的重载 如: int a(String str){}与 void a(String str){}不构成方法重载
  3. 只有形参的名称不同, 不构成方法的重载 如: int a(String str){}与 int a(String s){}不构成方法重载

【示例】方法重载

public class Test21 {
    public static void main(String[ ] args) {
        System.out.println(add(3, 5));// 8
        System.out.println(add(3, 5, 10));// 18
        System.out.println(add(3.0, 5));// 8.0
        System.out.println(add(3, 5.0));// 8.0
// 我们已经见过的方法的重载
        System.out.println();// 0 个参数
        System.out.println(1);// 参数是 1 个 int
        System.out.println(3.0);// 参数是 1 个 double
    }
    /** 求和的方法 */
    public static int add(int n1, int n2) {
        int sum = n1 + n2;
        return sum;
    }
    // 方法名相同,  参数个数不同,  构成重载
    public static int add(int n1, int n2, int n3) {
        int sum = n1 + n2 + n3;
        return sum;
    }
    // 方法名相同,  参数类型不同,  构成重载
    public static double add(double n1, int n2) {
        double sum = n1 + n2;
        return sum;
    }
// 方法名相同,  参数顺序不同,  构成重载
public static double add(int n1, double n2) {
    double sum = n1 + n2;
    return sum;
}
    //编译错误:  只有返回值不同,  不构成方法的重载
    public static double add(int n1, int n2) {
        double sum = n1 + n2;
        return sum;
    }
    //编译错误:  只有参数名称不同,  不构成方法的重载
    public static int add(int n2, int n1) {
        double sum = n1 + n2;
        return sum;
    }
}

practice:
定义一个方法处理公司的迟到问题:
(1) 输入: 迟到时间, 月薪。
(2) 处理逻辑:
1 迟到 1-10 分钟, 警告。
2 迟到 11-20 分钟, 罚款 100 元。
3 迟到 21 分钟-30 分钟, 罚款 200 元。
4 迟到 30 分钟以上, 扣除半日工资。
5 迟到 1 小时以上, 按照旷工计算, 扣除 3 日工资。
(3) 输出: 罚款金额

public class TestMethod2 {
    /**
     * (1)输入参数:迟到时间,月薪。
     * (2)处理逻辑:
     * ①迟到1-10 分钟,警告。
     * ②迟到11-20 分钟,罚款100 元。
     * ③迟到21分钟-30 分钟,罚款200 元。
     * ④迟到30 分钟以上,扣除半日工资。
     * ⑤迟到1小时以上,按照旷工计算,扣除3 日工资。
     * (3)输出罚款金额
     */
    public static int late(int lateMinute,double salary){
        int fakuan = 0;       //罚款
        if(lateMinute<11){
            System.out.println("警告! !不能迟到!!");
        }else if(lateMinute<21){
            fakuan = 100;
        }else if(lateMinute<31){
            fakuan = 200;
        }else if(lateMinute<61){
            fakuan = (int)(salary/(21.75*2));     //21.75 指的是:月平均工作日
        }else{
            fakuan = (int)(salary*3/(21.75));
        }

        System.out.println("迟到时间:"+lateMinute+",罚款: "+fakuan);
        return fakuan;
    }
    public static void main(String[] args) {
        late(45,42000);
    }
}

递归结构

递归的基本思想就是“自己调用自己”。像深度优先搜索 ( DFS:Depth First Search) 等很多算法里都有用到。

递归结构包括两个部分:
口 定义递归头。 解决: 什么时候不调用自身方法。如果没有头, 将陷入死循环, 也就 是递归的结束条件。
口 递归体。 解决: 什么时候需要调用自身方法。

【示例】使用递归求 n!

public class Test22 {
    public static void main(String[ ] args) {
        long d1 = System.curentTimeMilis();
        factorial(10);
        long d2 = System.curentTimeMilis();
        System.out.printf("递归费时:" +(d2-d1));   //耗时:  32ms
    }
    /** 求阶乘的方法*/
    static long   factorial(int n){
        if(n==1){//递归头
            return 1;
        }else{//递归体
            return n*factorial(n-1);//n! = n * (n-1)!
        }
    }
}

【示例】使用循环求 n!

public class Test23 {
    public static void main(String[ ] args) {
        long d3 = System.curentTimeMilis();
        int a = 10;
        int result = 1;
        while (a > 1) {
            result *= a * (a - 1);
            a -= 2;
        }
        long d4 = System.curentTimeMilis();
        System.out.println(result);
        System.out.printf("普通循环费时:  " + (d4 - d3));
    }
}

递归的缺陷
算法简单是递归的优点之一。
但是递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重。
上面示例中递归和循环的运行结果对比
在这里插入图片描述

面向对象编程(Object Oriented Programing)

表格结构和类结构

在这里插入图片描述
雇员类和雇员表的结构完全一样。只不过,雇员类增加了数据的类型而已。

-表格的动作和类的方法

在这里插入图片描述

-对象对应“表中的行数据”

在这里插入图片描述

在面向对象编程中,下面三句话记住:

  1. 表结构对应:类结构
  2. 一行数据对应:一个对象
  3. 表中所有数据对应:这个类的所有对象
//下面的四行数据,我们使用四个对象就需要这样表示(假设有对应的构造方法, 如下代码是示意,非真实代码):
emp1 = new Employee(ID:1001, name:"高小一", job:"程序员", baseSalary:20000, salary2:0, hiredate:"9 月 1 日", address:"北京"); 
emp2 = new Employee(ID:1002, name:"高小二", job:"前台", baseSalary:5000, salary2:0, hiredate:"9 月 2 日", address:"北京"); 
emp3 = new Employee(ID:1003, name:"高小三", job:"销售员", baseSalary:3000, salary2:15000, hiredate:"9 月 1 日", address:"郑 州");
emp4 = new Employee(ID:1004, name:"高小四", job:"财务", baseSalary:5000, salary2:0, hiredate:"9 月 2 日", address:"上海");

面向过程和面向对象思想

面向过程适合简单、不需要协作的事务,重点关注如何执行。
面向对象可以帮助我们从宏观上把握、从整体上分析整个系统。【面向对象(Oriented-Object)思想更契合人的思维模式。我们首先思考的是“怎么设计这个事物?”但具体到实现部分的微观操作(就是一个个方法),仍然需要面向过程的思路去处理。】

-面向过程和面向对象的区别

·面向对象和面向过程思想的总结
 都是解决问题的思维方式,都是代码组织的方式。
面向过程是一种“执行者思维”,解决简单问题可以使用面向过程。
面向对象是一种“设计者思维”,解决复杂、需要协作的问题可以使用面向对象。
 面向对象离不开面向过程:
 宏观上:通过面向对象进行整体设计
 微观上:执行和处理数据,仍然是面向过程。

面向对象是“设计者思维”

面向对象是一种“设计者思维”。
设计时,先从问题中找名词,然后确立这些名词哪些可以作为类,再根据问题需求确定的类的属性和方法,确定类之间的关系。

-面向对象分析: 写诗

在这里插入图片描述
先从场景中找出名词,以使用表格来表示。
在这里插入图片描述
分析完上面这些 Object 后,我们需要进行组合。把这些 Object 融合到一个场景。

-面向对象分析: 写小说

写小说本质上和设计软件是一样的,根据想要表达的内容,设计不同的场景、设计不同 的任务。
设计完成后,作者再按照一章一章的完成写作(执行阶段)。

以短篇小说《茶馆》为例,简单分析“面向对象设计方式写小说”的过程

  1. 明确小说主要内容和目标
    在这里插入图片描述

  2. 人物设计分析
    在这里插入图片描述

  3. 整体事件设计
    在这里插入图片描述

-对象的进化史(数据管理和企业管理共通之处)

在这里插入图片描述

总结
 对象说白了也是一种数据结构(对数据的管理模式),将数据和数据的行为放到了一起。
 在内存上,对象就是一个内存块,存放了相关的数据集合!
 对象的本质就一种数据的组织方式!

-对象和类的详解

类:class。
对象:Object,instance(实例)。(以后我们说某个类的对象,某个类的实例,是一样的意思)

 类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
 类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

类的定义

【示例】类的定义方式

// 每一个源文件必须有且只有一个public class,并且类名和文件名保持一致!
public class Car { 
}
class Tyre { // 一个Java文件可以同时定义多个class 
}
class Engine {
}
class Seat { 
}

对于一个类来说,有三种成员:属性 field、方法 method、构造器 constructor。
在这里插入图片描述

-属性 (field 成员变量)

属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。 在定义成员变量时可以对其初始化,如果不对其初始化,Java 使用默认的值对其初始化。
在这里插入图片描述
属性定义格式:

[修饰符] 属性类型 属性名 = [默认值] ;

-方法

在这里插入图片描述

方法用于定义该类或该类实例的行为特征和功能实现。方法是类和对象行为特征的抽象。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。

[修饰符] 方法返回值类型 方法名(形参列表) { 
// n 条语句
}

【示例】编写简单的学生类

public class SxtStu { 
	//属性(成员变量)
 	int id;
 	String sname; 
 	int age; 
 	//方法
  	void study(){ 
  		System.out.println("我正在学习!"); 
  }
	//构造方法 
	SxtStu(){ 
	} 
}

简单内存分析(帮助理解面向对象)在这里插入图片描述

-构造方法(构造器 constructor)

构造器用于对象的初始化,而不是创建对象【构造方法是负责初始化(装修),不是建房子】
在这里插入图片描述
声明格式:

[修饰符] 类名(形参列表){
	//n 条语句 
} 

构造器 4 个要点:

 构造器通过 new 关键字调用!!
 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return 返回某个值。
 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义 则编译器不会自动添加!
 构造器的方法名必须和类名一致!

practice:
定义一个“点”(Point)类用来表示二维空间中的点(有两个坐标)。要求如下:
 可以生成具有特定坐标的点对象。
 提供可以计算该“点”距另外一点距离的方法

class Point { 
    double x, y;
    public Point(double _x, double _y) { 
        x = _x; 
        y = _y; 
    }
    public double getDistance(Point p) { 
        return Math.sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y)); 
    }
    public static void main(String[ ] args) { 
        Point p1 = new Point(3.0, 4.0);
        Point origin = new Point(0.0, 0.0); 
        System.out.println(p1.getDistance(origin)); 
    } 
}

构造方法的重载

构造方法也是方法。与普通方法一样,构造方法也可以重载
【示例 】构造方法重载(创建不同用户对象)

public class User {
    int id; // id
    String name; // 账户名
    String pwd; // 密码
    public User() {

    }
    public User(int id, String name) {//如果方法构造中形参名与属性名相同时,需要使用 this 关键字区分属性与形参。 this.id 表示属性 id;id 表示形参 id
        this.id = id;
        this.name = name;
    }
    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
    public static void main(String[ ] args) {
        User u1 = new User();
        User u2 = new User(101, "大嗲嗲");
        User u3 = new User(100, "小嗲嗲", "123456");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值