Java学习之路之week3day1

Java学习之路之week3

向Java程序员的目标前进!

day10

学习内容

面向对象

面向对象的思想是把关于做一件事所有的细节都记录好,保存起来(对要使用的方法进行类封装),将来再做这个事情时,不用再去想具体的实现细节(不用再去找具体的方法),只要找到这个存档(类),就可以直接用了。而面向对象的本质是基于面向过程的。

注:接下来的几天会花大量时间学习面向对象

面向过程

面向过程的代表语言是C语言

面向过程的思想:亲力亲为的

比如拿到一个需求:

面向过程会这么做:

  1. 拿到一个需求,分析步骤

  2. 用代码实现步骤

  3. 测试

面向对象会这么做:找一个对象完成这个事情

再举一个生活中的例子:炒菜

面向过程会这么做:

去买菜—>买回来择菜—>洗菜—>切菜—>起锅烧油—>炒菜—>出锅

有了面向对象就可以这么做:

找一个对象给你做饭,等待出锅

注意事项:不能说“万物皆对象”,虽然生活中处处是面对对象的例子,但是还是要具体举例,说明思想。

面向对象的思想特点

  1. 是一种更符合我们思想习惯的思想
  2. 让简单的事情复杂化
  3. 角色转变:我们从执行者变成了指挥者

面向对象的设计原则:就是不断地创建对象、使用对象、指挥对象做事情。

面对对象的特征:封装、继承、多态

类与对象关系

Java中最基本的单元——类

类是描述现实世界事物的属性和行为的统称

类的另一种定义:类是描述一组事物的属性和行为的集合

举例:在现实事物中有学生类,在学生类中存在学生事物的属性,比如每个学生都有姓名、年龄、性别、身高、爱好这样的属性(对应成员变量),也有着吃饭、睡觉、学习、玩等等的行为(对应成员方法)。

成员方法的格式:

/*
 成员方法:在前面所学基础上去掉static 	
*/
	public 返回类型 方法名(参数类型1 变量名1,参数类型2 变量名2...){
        //业务代码
        //如果有返回值类型,则需要带上return语句,返回值类型为void则不需要
    }

上面的举例也可以使用代码体现出来:

	//定义学生类
	class Student{
        //成员变量——描述现实事物中的属性(类中方法外定义的变量),采用小驼峰命名法
        String name;//姓名
        int age;//年龄
        String gender;//性别
        //...
        //成员方法
        //学习
        public void study(){
            System.out.println("学生正在学习面向对象...");
        }
        //睡觉
        public Stirng sleep(){
            return "学生正在睡觉...";
        }
        //吃饭
        public void eat(){
            System.out.println("学生正在吃饭...");
        }
    }

上面的代码中只是描述了学生类(学生类是泛指)的属性和行为,我们并没有给出具体的学生是谁,但在定义的类中我们需要填充信息,否则定义就感觉是空洞的。所以我们需要用代码将具体的学生事物体现出来,接下来就是创建对象。

对象的创建及调用:

	//创建对象格式:
	类名 对象名 = new 类名();
	//对象属性调用格式(注意数据类型):
	对象名.成员变量(属性) = 数据值;
	//对象方法调用格式:
	//有返回值则返回结果,没有返回值则单独调用
	对象名.成员方法(行为);

继续上面的例子:

	Student student = new Student();
	System.out.println("学生姓名是:"+student.name+",学生年龄是:"+student.age+",学生性别是:"+student.gender);
	
	student.name = "aaa";
	student.age = 20;
	student.gender = "女";

	System.out.println("学生姓名是:"+student.name+",学生年龄是:"+student.age+",学生性别是:"+student.gender);
	student.study();
	String result = student.sleep();
	System.out.println(result);
	student.eat();

类与对象的关系

类和对象是相辅相成且一一对应的关系。类是描述一组事物的属性和行为的,是一种泛指,而对象是描述具体的事物。

类与对象练习

需求1:定义一个手机类,来描述现实世界事物的"手机事物"。

成员变量—属性:

  • 品牌: brand

  • 价格 price

  • 颜色 color

  • 内存 memory

成员方法—行为:

  • callPhone(String name):打电话
  • sendMsg(String name):发短信
  • playGame():玩游戏
public class Phone {
    //成员变量
    String brand ; //品牌
    int price ;//价格
    String color ; //颜色
    String memory ; //机身内存
    //成员方法
    public void callPhone(String name){
        System.out.println("手机给"+name+"打电话了");
    }
    public void sendMsg(String name){
        System.out.println("给"+name+"在发短信");
    }
    public void playGame(String gameName){
        System.out.println("使用手机正在玩"+gameName);
    }
}

需求2:

  • 创建两个手机类对象,分别输出它们的对象名称
  • 以及重写给成员变量赋值,输出成员信息
  • 然后定义第三个名称p3 ,将第一个手机类对象赋值给p3
  • 给p3的成员变量重写赋值
public class PhoneTest {
    public static void main(String[] args) {
        //创建第一个手机类对象
        Phone p1 = new Phone() ;
        System.out.println(p1);
        p1.brand = "小米10" ;
        p1.price = 1399 ;
        p1.color = "黑色";
        p1.memory = "64G" ;
        System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
        
        System.out.println("-----------------------------------") ;
        
        Phone p2 = new Phone() ;
        System.out.println(p2);
        p2.brand = "锤子手机" ;
        p2.price = 2799 ;
        p2.color = "棕色";
        p2.memory = "128G" ;
        System.out.println(p2.brand+"---"+p2.price+"---"+p2.color+"---"+p2.memory) ;

        System.out.println("------------------------------------") ;

        //定义第三个手机类,但是没有进行new
        //将第一个手机类对象赋值给第三个变量p3
        Phone p3 = p1 ;
        p3.brand = "华为mate40Pro保时捷版" ;
        p3.price = 14999 ;
        p3.color = "天空灰" ;
        p3.memory = "256G" ;
        System.out.println(p1);
        //输出的p1访问的成员信息
        System.out.println(p1.brand+"---"+
                p1.price+"---"+p1.color+"---"+p1.memory) ;
        
        //调用方法
        p1.callPhone("aaa") ;
        p1.playGame("原神");
        p1.sendMsg("bbb");
    }
}

创建一个对象的内存图解

用上面需求1和需求2的手机类例子进行部分代码的图解:

Java学习之路之week3day1

创建多个对象的内存图解

继续用上面需求1和需求2的手机类例子进行代码的图解:

Java学习之路之week3day1

上面的图解说明了:

  • 栈内存中的多个栈可以指向同一个堆内存
  • 数组和类都是引用数据类型
  • 成员变量永远跟堆内存有关

封装

从一个例子说起

/**
 * 需求:描述一个学生事物,有姓名,和年龄两个属性
 * 然后写一个测试类,测试学生的信息
 */
class Student{
    String name;
    int age;
    
    public void showStudent(){
        System.out.println("学生的姓名是:"+name+",年龄是:"+age);
    }
}

class StudentTest{
    public static void main(String[] args){
        Student student = new Student();
        student.name = "爱学cs的小陈";
        student.age = -45;
        student.showStudent();
    }
}

写完之后运行结果如下:

学生的姓名是:爱学cs的小陈,年龄是:-45

运行结果没有报错,但是根据常识,我们发现年龄的数据不合适。在这个简单的程序中我们可以轻松的发现错误,可是当后面我们学习了数据库后,数据库中如果有像运行结果这样的非法数据,我们不能容忍这样的数据被使用。所以以现在我的学习水平,可以这个程序进行改进。

为了使数据在合适的范围内,我们可以在Student类中定义成员方法,校验年龄的合法范围。如果数据<0或者>120,则提示"非法数据",否则就将变量赋值给成员变量age。改进的程序代码如下:

/**
 * 需求:描述一个学生事物,有姓名,和年龄两个属性
 * 然后写一个测试类,测试学生的信息
 */
class Student{
    String name;
    int age;
    
    public void setAge(int a){
        if(a<0 || a> 120){
            System.out.println("年龄数据非法!");
        }else{
            age = a;
        }
    }
    
    public void showStudent(){
        System.out.println("学生的姓名是:"+name+",年龄是:"+age);
    }
}

class StudentTest{
    public static void main(String[] args){
        Student student = new Student();
        student.name = "爱学cs的小陈";
        student.setAge = -45;
        student.showStudent();
        System.out.println("---------------------------");
        student.setAge(18);
        student.showStudent();
        System.out.println("-------------------------------");
        student.age = -45;
        student.showStudent();
    }
}

改进程序的运行结果如下:

年龄数据非法!
学生的姓名是:爱学cs的小陈,年龄是:0
-------------------------------
学生的姓名是:爱学cs的小陈,年龄是:18
-------------------------------
学生的姓名是:爱学cs的小陈,年龄是:-45

在上述运行结果中,虽然添加了setAge()方法用来校验年龄,但是我们仍然可以通过绕过数据检验方法(setAge())直接访问age变量并修改数据值。由此可见,这样的改进仍然是有缺陷的。

在java中,为了避免这样的问题,我们可以采用封装的技术。

封装的概念

封装是指将一个对象的属性和实现细节私有化(亦称隐藏),仅提供了公共的访问方法。由于封装的性质,外部并不能直接访问,因而提高了代码的复用性和安全性。

封装的原则和方法:把不需要对外提供的内容都隐藏起来,仅提供提供公共方法对其访问。具体做法是将类中的成员变量加入private关键字前缀,并加入setter和getter方法。

private关键字:是一个权限修饰符,下面会单独介绍。

setter和getter方法:对外提供的公共访问方法,在开发环境(IDE)中可以自动生成,以后会介绍。

private关键字

private关键字是一个权限修饰符,用来对成员(成员方法和成员变量)进行访问范围控制。被private修饰的成员方法或成员变量,只能在当前类中访问。外界类不能直接访问,但是可以间接地通过公共访问方法来访问。下面看一个例子理解。

/**
 * 需求:获取PrivateDemo中num和num2的值并输出
 */
class PrivateDemo{
    int num = 20;
    private int num2 = 200;

    public void show(){
        System.out.println(num);
        System.out.println(num2);
    }
}

class TestPrivateDemo {
    public static void main(String[] args) {
        PrivateDemo p = new PrivateDemo();
        System.out.println(p.num);
        System.out.println(p.num2);
        System.out.println("--------------------------");
        p.show();
    }
}

如果运行了上面的程序,会报下面的错误(对包名进行了处理):

java: num2 在 com.xxx.PrivateDemo 中是 private 访问控制

原因就是在TestPrivateDemo类中直接访问了被private修饰的私有属性变量num2,所以当注释了18行代码后,程序就可以正常输出了。

博客难免会产生一些错误。如果写的有什么问题,欢迎大家批评指正。

上一篇:oracle to_date 函数


下一篇:JQuery 模糊匹配