【Java自学】搬砖中年人代码自学之路Lesson 6


话说每次发了文章之后总有个几十到几百的阅读量,但是多多少少还是希望跟我一样的萌新们能够给个大拇哥支持支持,希望大佬们能够降维打击一下说一句md好弱鸡哈哈哈哈哈哈哈哈哈哈哈哈。其实主要原因是因为自己跟着视频课程学,尤其是一些作业题,也不知道做的对不对,其实还是比较希望能有个人来交流的。手下有个小孩儿是学计算机的,但是中年基层小领导的可笑面子让我不能接受我自己问他问题,所以干脆就跑上来,一方面记录一下自己的学习过程,一方面借着互联网来当个不露脸的键盘侠,即使被大家评头论足,其实也不会觉得尴尬不好意思

其实近来的学习一直是断断续续的,之前在知乎上看到一篇文章,说Java学习最好是不要间断,一旦间断就会出现知识断层,但是感觉目前阶段好像还好,断了一段时间,重新接上其实也能勉强跟的上,估计到后面难起来了之后就要连着学习了。而且最近其实比较纠结,因为前段时间隔离,吃睡都比较稳定,所以体重增长也比较稳定,已经成功突破180大关,最近正想着隔一天抽出一点时间去游个泳减个肥,所以感觉可能确实会继续保持这种断断续续的状态。

不过还有一件事儿比较纠结,可能最近该准备换工作的事儿了,又有点想认认真真的学完之后,看看Java能不能在我找工作的空窗期让我能够用它赚点小钱保证我的烟钱不断,其实想想还是有点小兴奋的。

走一步看一步吧!


⚠️面向对象⚠️    “大处着眼,小处着手”

⚠️面向对象⚠️  

一、Java面向对象学习的三条主线

        1. Java类及类的成员:属性、方法、构造器;代码块、内部类

        2. 面向对象的三大特征:封装性、继承性、多态性

        3. 其他关键字:this、super、static、final、abstract、interface、package、import等 

面向过程(POP:Procedure Oriented Programming)与面向对象(OOP:Object Oriented Programming)

        > 二者都是一种思想,面向对象是相对于面向过程而言的

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

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

                > 面向对象更强调运用人类在日常的思维逻辑中采用的思想方法与原则,如:抽象、分类、继承、聚合、多态等

        > 面向对象的三大特征

                > 封装(encapsulation)

                > 继承(inheritance)

                > 多态(polymorphism)

二、“把大象装进冰箱”:看似面向过程比面向对象要简洁,但是在实际编写代码,尤其是大项目的程序编写上,还是面向对象功能更加强大、结构更加清晰、过程更加简洁

        举例解读:有点像创业,小公司的时候更加像面向过程,人少,扁平;

                            但是公司一旦大了,如果不划分部门、职责,工作就会变得非常混乱

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

                > 把冰箱门打开

                > 抬起大象,塞进冰箱

                > 把冰箱门关闭

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

人{
    打开(冰箱){
        冰箱.打开();
    }

    抬起(大象){
        大象.进入(冰箱);
    }

    关闭(冰箱){
        冰箱.闭合();
    }
}

冰箱{
    打开(){

    }

    闭合(){

    }
}

大象{
    进入(冰箱){

    }
}

        3. 面向对象的三大特征

                > 封装(encapsulation)

                > 继承(inheritance)

                > 多态(polymorphism)

        4. 面向对象的思想概述

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

                > 面向对象分析方法、分析问题的思路和步骤

                        > 根据问题需要,选择问题所针对的现实世界中的实体

                        > 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类

                        > 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构

                        > 将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具

三、Java语言的基本元素:类和对象

        1. 类(class)和对象(object)是面向对象的核心概念

                > 类:是对一类事物的描述,是抽象的、概念上的定义

                > 对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)

                > 举例说明:「人」

                        > 类:抽象概念的人

                        > 对象:实实在在的某个人

                > 面向对象程序设计的重点是类的设计,具体的个体具备什么样的功能都是由类决定的,比如「你我他」需要睡觉,是因为「人」这个类的设计过程中就设置了需要睡觉的概念

                > 「类」的设计,其实就是类的成员的设计

        2. “万事万物皆对象”

        3. Java类及类的成员

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

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

                        > 属性:对应类中的成员变量

                        > 行为:对应类中的成员方法

                                field = 属性 = 成员变量 = 域、字段(这种叫法相对较少,多数来自于外文书籍)

                                method = (成员)方法 = 函数

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

//测试类
public class PersonTest{
    public static void main(String[] args){
        //创建Person类的对象
        Person p1 = new Person();//类似于Scanner scanner = new Scanner(System.in);

        //调用对象的属性:「对象.属性」
        p1.name = "Tom";
        p1.isMale = true;
        p1.age = 31;
        System.out.println(p1.name);

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

        Person p2 = new Person();
        System.out.println(p2.name);//Tom?    报错?    输出的是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 ear(){
        System.out.println("人可以吃饭");
    }
    
    public void sleep(){
        System.out.println("人可以睡觉");
    }

    public void talk(String language){
        System.out.println("人可以说话,使用的语言是:" + language);
    }
}

四、类和对象的使用(面向对象思想落地的实现)

        1. 创建类:设计类的成员

        2. 创建类的对象:

        3. 通过"对象.属性"、"对象.方法"调用对象的结构

        4. 如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的),意味着,如果我们修改一个对象的属性A,则不影响另外一个对象属性A的值

五、对象的内存解析

编译完源程序之后,生成一个或多个字节码文件

我们使用JVM中的类的家在期和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析

《JVM规范》

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

        2. 栈(Stack):通常所说的栈,是指虚拟机栈,而非本地方法栈。虚拟机栈用于存储局部变量

            局部变量表存放了编译器可知长度的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型),它不等同于对象本身,是对象在堆内存放的首地址。方法执行完,自动释放

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

六、类中属性的使用

        属性(成员变量) vs 局部变量

        1. 相同点:

                > 定义变量的格式是一样的:数据类型 变量名 = 变量值;

                > 先声明,后使用

                > 变量都有其对应的作用域,超过作用域范围内就失效了

        2. 不同点:

                > 通过在类中声明的位置的不同做区分

                        > 属性:直接定义在类的一对{}内

                        > 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

                > 关于权限修饰符的不同

                        > 属性:可以在声明属性时,指明其权限,使用权限修饰符

                           常用的权限修饰符:缺省(即属性前没有东西)、private、public、protected

                           权限修饰符作用:体现了结构被调用时候的可见性的大小 — — 封装性时候主要讨论

                           目前,大家声明属性时,都使用缺省就可以了

                        > 局部变量:不可以使用权限修饰符的,也可以理解为被方法的权限修饰符代替了

                > 关于默认初始化值的情况

                        > 属性:类的属性,根据其类型,都有默认初始化值

                                > 整型(byte、short、int、long) --> 0

                                > 浮点型(float、double) --> 0.0

                                > 字符型(char) --> 0 (或'\u0000')

                                > 布尔型(boolean) --> false

                                > 引用数据类型(类、数组、接口等) --> null

                        > 局部变量:没有默认初始化值。意味着,我们在调用局部变量之前,一定要显示赋值

                                > 特别的:形参在调用时,我们赋值即可

                > 在内存中加载的位置

                        > 属性(非static):加载到堆空间

                        > 局部变量:加载到栈空间

七、类中方法的声明和使用

//测试类
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) {// <--这个language叫做形参,是局部变量
		System.out.println("我们使用:" + language + "进行交流");
	}

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

        > 方法:描述类应该具有的功能。

           比如:Math类,squrt()、random()...

                      Scanner类,nextXxx()。。。

                      Arrays类,sort()、binarySearch()、toString()、equals()...

                > 举例:

                        public void eat() {}

                        public void sleep(int hour) {}

                        public String getName() {}

                        public String getNation(String nation) {}

 

                > 无形参:

                        > 无返回值:void(){}

                        > 有返回值:返回值的类型 方法名(){}

                > 有形参:

                        > 无返回值:void 方法名(形参列表){}

                        > 有返回值:返回值的类型 方法名(形参列表){}

                > 方法的声明格式:

                   权限修饰符 返回值类型 方法名(形参列表「可有可无,有形参的时候可以不止一个,例如binarysearch」){

                           方法体

                   }

                   注意:static、final、abstract来修饰的方法,后面再讲

                > 说明:

/*
 * 练习1:
 * 创建一个Person类,其定义如下:
 * 
 * Person
 * name:String
 * age:int
 * sex:int
 * ----------------
 * +study():void
 * +showAge():void
 * +addAge(int i):int
 * 
 * 要求:
 * 	1)创建Person类的对象,设置该对象的name、age和sex属性
 * 	   调用study方法,输出字符串"studying"
 * 	   调用showAge()方法显示age值
 * 	   调用addAge()方法,给对象的age属性值加2岁
 * 	2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系
 */

public class Person{
    String name;
    int age;
    /**
    *sex:1表明是男性
    *sex:2表明是女性
    */
    int sex;

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

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

    public int addAge(int a){
        age += a;
        return age;
    }
}
public class PersonTest{
    public static void main(String[] args){
        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);

        System.out.println(p1.age);//20,p1的age其实已经在addAge方法中的返回值赋值为20了,newAge相当于是被赋值过的age再赋值了一次,所以返回值是20

        Person p2 = new Person();
        p2.showAge();//0
        p2.addAge(10);
        p2.showAge();//10

        p1.showAge();//20
    }
}

 

                        > 关于权限修饰符:默认方法的权限修饰符先都使用public

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

                        > 返回值类型:有返回值 vs 没有返回值

                                > 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中需要使用return关键字,格式「return 数据;」来返回指定类型的变量或常量,否则程序会报错

                                   如果方法没有返回值,则方法声明时,使用void来表示。通常没有返回值的方法中,不需要使用return关键字,但是,如果使用的话,只能用格式「return;」表示结束此方法

                                > 如何确定定义方法时该不该有返回值?

                                        > 看题目要求

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

                        > 方法名:属于标识符,遵循标识符的规则和规范,「见名知意」

                        > 形参列表:方法可以声明0个、1个或多个形参

                                > 格式:数据类型1 形参1,数据类型2 形参2,.....

                                > 如何确定定义方法时该不该定义形参?

                                        > 看题目要求

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

                        > 方法体:方法功能的体现

                > return关键字的使用

                        > 使用范围:使用在方法体中

                        > 作用:

                                > 结束一个方法,类似于break;

                                > 针对于有返回值类型的方法,使用格式「return 数据;」方式返回所要的数据

                        > 注意:return后面不可以有执行语句

八、方法的使用:

        > 可以调用当前类的属性、方法

                > 特殊:方法A中,又调用了方法A —> 递归方法

           方法中,不可以定义方法

九、变量的分类

        > 方式一:根据数据类型分类

                > 基本数据类型(primitive type)

                        > 数值型

                                > 整数类型:byte、short、int、long

                                > 浮点类型:float、double

                        > 字符型:char

                        > 布尔型:boolean

                > 引用数据类型(reference type)

                        > 类:class <— 字符串在这里

                        > 接口:interface

                        > 数组:[]

        > 方式二:按照在类中声明的位置分类

                > 成员变量

                        > 实例变量:不以static修饰

                        > 类变量:以static修饰

                > 局部变量

                        > 形参:方法、构造器中定义的变量

                        > 方法局部变量:在方法内定义

                        > 代码块局部变量:在代码块内定义

⚠️一些练习题

/*
 * 声明一个日期类型MyDate:
 * 属性:
 * 年year,月month,日day
 * 创建两个日期对象,分别赋值为:你的出生日期,你对象的出生日期,并显示信息
 */

public class DateTest{
    public static void main(String[] args){
        MyDate d1 = new MyDate();
        d1.year = 1991;
        d1.month = 6;
        d1.day = 30;

        MyDate d2 = new MyDate();
        d2.year = 1991;
        d2.month = 7;
        d2.day = 14;

        System.out.println("我的" + d1.info());
        System.out.println("我对象的" + d2.info());
    }
}

class MyDate{
    int year;
    int month;
    int day;

    public String info(){
        return "出生日期为:" + year + "年" + month + "月" + day + "日";
    }
}
/*
 * 练习2:利用面向对象的编程方法,设计类Circle计算圆的面积
 */

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);
    }
}

class Circle{
    double radius;
    double area;

    public double findArea(){
        area = Math.PI * radius * radius;
        return area;
    }
}
/*
 * 1)编写程序:声明一个method方法,在方法中打印一个10 * 8的*型矩形,在main方法中使用该方法
 * 2)修改上一个程序,在method方法中,除打印一个10 * 8的*型矩形外,再计算该矩形的面积,并将其作为方法的返回值,在main方法中调用该方法,接受返回的面积值并打印
 * 3)修改上一个程序,在method方法中提供m和n两个参数,方法中打印一个m * n的*型矩形,并计算该矩形的面积,将其作为方法返回值,在main方法中调用该方法,接受返回的面积值并打印
 */

public class RectangleTest{
    public static void main(String[] args){
        RectangleTest test = new RectangleTest();
        int area = test.method();
        System.out.println("面积为:" + area);
    }

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

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

    //第三问
    public int method(int m,int n){
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                System.out.print("* ");
            }
            System.out.println();
        }
        retrun m * n;
    }
}
/*
 * 练习4:
 *  > 定义数组题目
 *  > 定义类Student,包含三个属性:学号number(int)、年级state(int)、成绩score(int),创建20个学生对象,学号为1-20,年级和成绩都有随机数确定
 *  > 问题一:打印出3年级(state值为3)的学生信息
 *  > 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
 *  
 *  > 提示:生成随机数Math.random(),返回值类型double
 *  > 四舍五入取整数:Math.round(double d),返回值类型long
 */

public class StudentTest{
    public static void main(String[] args){
        //声明Student类的数组
        Student[] stus = new Student[20];

        //为数组元素赋值
        for(int i = 0;i < 20;i++){
            //创建数组元素
            stus[i] = new Student();
            //给Student对象的属性赋值
            stus[i].number = i + 1;
            Stus[i].state = (int)(Math.Random() * (6 - 1 + 1) + 1);//年级范围:1-6年级
            Stus[i].score = (int)(Math.Random() * (100 - 0 + 1) + 0);//成绩范围:0-100分
        }
        
        //遍历学生数组
        for(int i = 0;i < stus.length;i++){
            System.out.println("学号:" + stus[i].number + ",年级:" + stus[i].state + ",成绩:" + stus[i].score);
        }

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

        //问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
        //使用冒泡排序对学生成绩进行排序
        for(int i = 0;i < stus.length - 1;i++){
            for(int j = 0;j < stus.length - 1 - i;j++){
                Student temp = new Student();
                if(stus[j].score > stus[j + 1].score){
                    temp = stus[j + 1];
                    stus[j + 1] = stus[j];
                    stus[j] = temp;
                }
            }
        }

        //遍历学生信息
        for(int i = 0;i < stus.length;i++){
            System.out.println("学号:" + stus[i].number + ",年级:" + stus[i].state + ",成绩:" + stus[i].score);
        }
    }
}

class Student{
    int number;//学号
    int state;//年级
    int score;//成绩
}
/*
 * 练习4:【升级版】
 *  > 定义数组题目
 *  > 定义类Student,包含三个属性:学号number(int)、年级state(int)、成绩score(int),创建20个学生对象,学号为1-20,年级和成绩都有随机数确定
 *  > 问题一:打印出3年级(state值为3)的学生信息
 *  > 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
 *  
 *  > 提示:生成随机数Math.random(),返回值类型double
 *  > 四舍五入取整数:Math.round(double d),返回值类型long
 */

public class StudentTest{
    public static void main(String[] args){
        //声明Student类的数组
        Student[] stus = new Student[20];

        //为数组元素赋值
        for(int i = 0;i < 20;i++){
            //创建数组元素
            stus[i] = new Student();
            //给Student对象的属性赋值
            stus[i].number = i + 1;
            Stus[i].state = (int)(Math.Random() * (6 - 1 + 1) + 1);//年级范围:1-6年级
            Stus[i].score = (int)(Math.Random() * (100 - 0 + 1) + 0);//成绩范围:0-100分
        }

        StudentTest test = new StudentTest();

        test.print(stus);
        test.searchState(stus,3);
        test.bubbleSort(stus);
    }

    //遍历学生数组的方法,形参输入对应数组,即可完成操作
    public void print(Student[] stus){
        for(int i = 0;i < stus.length;i++){
            System.out.println(stus[i].info());
        }
    }

    //打印指定年级学生信息的方法,形参输入对应的年纪,即可完成操作
    public void searchState(Student[] stus,int state){
        for(int i = 0;i < stus.length;i++){
            if(stus[i].state == state){
                System.out.println(stus[i].info());
            }
        }
    }

    //冒泡排序方法,排序后对数组进行遍历
    public void bubbleSort(Student[] stus){
        for(int i = 0;i < stus.length - 1;i++){
            for(int j = 0;j < stus.length - 1 - i;j++){
                Student temp = new Student();
                if(stus[j].score > stus[j + 1].score){
                    temp = stus[j + 1];
                    stus[j + 1] = stus[j];
                    stus[j] = temp;
                }
            }
        }
        
        for(int i = 0;i < stus.length;i++){
            System.out.println(stus[i].info());
        }
    }
}

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

    public String info(){
        return "学号:" + number + ",年级:" + state + ",成绩:" + score;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值