java语言的入门总结与归纳(四)

前言

本小节讲解了java语言基础语法中有关类的知识,其中的图来自慕课网学习截图。
同时,制作了一个阶段性的小程序——“答答租车”小程序。

一、有关于类的核心知识点

  1. 类是对象的类型,是具有相同属性和方法的一组对象的集合
  2. 属性的概念:对象具有的各种特征,每个对象的每个属性都拥有特定值
  3. 方法的概念:对象执行的操作
  4. 类与对象的关系:类是抽象的概念,而对象是一个具体的实体,对象是类的实例化和具体化。
  5. 所有Java程序都以类(class)为组织单元
  6. 定义一个类的步骤:
    · 定义类名
    · 编写类的属性
    · 编写类的方法
    例:
public class 类名{
   // 定义属性部分(成员变量)
   属性1的类型 属性1;
   属性2的类型 属性2;
    ...
   属性n的类型 属性n;
   // 定义方法部分
   方法1;
   方法2;
    ...
   方法m;
}
  1. 使用Java中的对象的步骤:
    · 创建对象:类名 对象名 = new 类名();
    · 使用对象:引用对象的属性:对象名.属性; 引用对象的方法:对象名.方法名();
  2. 成员变量与局部变量
    · 成员变量:在类中定义,用来描述对象的属性。成员变量的作用域在整个类内部都是可见的。成员变量的默认值为0
    · 局部变量:在类的方法中定义,在方法中临时保存数据,用来做一些数据的处理等。局部变量的作用域仅限于定义它的方法。Java并不会给局部变量赋予初始值
    · 在同一个方法中,不允许有同名局部变量;在不同的方法中,可以有同名局部变量
    · 两类变量同名时,局部变量具有更高的优先级,即‘就近原则’。
  3. Java语言中的构造方法
    · 使用new + 构造方法创建一个新的对象
    · 构造方法是定义在Java类中的一个用来初始化对象的成员变量的方法;构造方法与类同名且没有返回值。
    · 当没有指定构造方法时,系统会自动添加无参的构造方法
    · 当有指定构造方法,无论是有参、无参的构造方法,都不会自动添加无参的构造方法。
    · 构造方法的重载:方法名相同,但参数不同的多个方法,调用时会自动根据不同的参数选择相应的方法。
    · 构造方法不但可以给对象的属性赋值,还可以保证给对象的属性赋一个合理的值
    · 语法格式:
public 构造方法名(){
   // 初始化代码
}
  1. Java语言中的静态成员(类成员):被static修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。static可以修饰变量、方法和代码块
  2. Java中可以通过初始化块进行数据赋值。如:
public class HelloWorld{
    String name;  // 定义一个成员变量
    // 通过初始化块为成员变量赋值
    {
        name = “你好”;
    }
}

在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块。如果使用static修饰初始化块,就称为静态初始化块。

二、面向对象的三大特性之封装

  1. 封装概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。即:隐藏属性,通过方法来得到属性的值。
  2. 封装好处:只能通过规定的方法访问数据;隐藏类的实例细节,方便修改和实现。
  3. 封装的实现步骤:
    · 修改属性的可见性
    · 创建getter/setter方法
    · 在getter/setter方法中加入属性控制语句,对属性值的合法性进行判断
  4. Java中的包
    · 包的作用:管理Java文件,解决同名文件冲突的问题
    · 定义包:package 包名
    · 包的使用:
    1)可以通过import关键字,在某个文件使用其它文件中的类,如:import java.util.Scanner;
    2)在Java中,包的命名规范是全小写字母拼写
  5. Java中的访问修饰符:可以修饰属性和方法的访问范围
    访问修饰符的图示
  6. Java中的this关键字
    · this关键字代表当前对象
    1)this.属性 操作当前对象的属性
    2)this.方法 调用当前对象的方法
    · 封装对象的属性的时候,经常会使用this关键字,例如在使用getter/setter方法的时候,常常会碰到‘参数名’与‘属性名’相同的情况,这时我们可以通过在属性名之前加上this关键字来加以区分。
  7. Java中的内部类
    · 概念:定义在另外一个类里面的类称为内部类;与之对应,包含内部类的类称为外部类。
    · 内部类的主要作用:
    1)提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
    2)内部类的方法可以直接访问外部类的所有数据,包括私有的数据
    3)内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
    · 内部类可分为以下四种:
    1)成员内部类(又称为普通内部类)
    2)静态内部类
    3)方法内部类
    4)匿名内部类
  8. 内部类之成员内部类
    · 使用方法:
    1)内部类相当于外部类的一个成员变量的位置,可以使用任意访问控制符,如public、protected、private等
    2)内部类中的方法可以直接访问外部类中的数据,而不受访问控制符的影响。
    3)定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去new一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类();
  9. 内部类之静态内部类
    · 特点:
    1) 静态内部类不能直接访问外部类的非静态成员,但可以通过new 外部类().成员的方式访问。
    2)如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过‘成员名’直接调用外部类的静态成员。
    3)创建静态内部类的对象时,不需要外部类的对象,可以直接创建:内部类 对象名 = new 内部类();
  10. 内部类之方法内部类
    · 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
    · 由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和static修饰符。

三、面向对象的三大特性之继承

  1. 继承的概念:Java中的继承是单继承的,继承是类与类的一种关系。
  2. 继承的优点:
    1)子类拥有父类的所有属性和方法
    2)实现代码复用
  3. 语法规则:class 子类 extends 父类
  4. 继承的初始化顺序:
    1)初始化父类再初始化子类
    2)先执行初始化对象中属性,再执行构造方法中的初始化
    即:先进行父类对象的属性初始化,接着执行父类的构造方法,然后再进行子类对象的属性初始化,最后再执行子类的构造方法。
  5. 方法的重写
    · 如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。
    · 语法规则:返回值类型、方法名、参数类型及个数都要与父类继承的方法相同,才叫方法的重写。
  6. Java中的final关键字的使用
    · 使用final关键字做标识有“最终的”含义
    · final可以修饰类、方法、属性和变量
    1)final修饰类,则该类不允许被继承
    2)final修饰方法,则该方法不允许被覆盖(重写)
    3)final修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值(但只能选其一)
    4)final修饰变量,则该变量的值只能赋一次值,即变为常量
  7. Java中的super关键字:在对象的内部使用,可以代表父类对象。
    · 可通过super关键字访问父类的属性
    · 可通过super关键字访问父类的方法
    · 子类在构造的过程当中必须调用其父类的构造方法,如果子类的构造方法中没有显式调用父类的构造方法,则系统默认调用父类无参的构造方法。即:程序隐式的在子类的构造方法中添加一句‘super();’代码调用父类的构造方法。
    · 如果显示的调用构造方法,必须在子类的构造方法的第一行。
    · 如果子类构造方法中既没有显式调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。
  8. Java中的Object类
    · Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。
    · Object类中的方法,适合所有子类。
    · 几个比较重要的方法
    1)toString()方法:在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串)。可以通过重写toString()方法表示出对象的属性。
    2)equals()方法:比较的是对象的引用是否指向同一块内存地址。当我们用‘new关键字’创建一个对象时,其实创建的是对象在内存中的地址,我们通过操作该地址间接操作了对象的值。

四、面向对象的三大特性之多态

  1. 多态的概念:对象的多种形态
  2. 继承是多态的实现基础
  3. 引用多态
    1)父类的引用可以指向本类的对象
    2)父类的引用可以指向子类的对象
  4. 方法多态
    1)创建本类对象时,调用的方法为本类方法
    2)创建子类对象时,调用的方法为子类重写的方法或者继承的方法
    3)不允许通过父类的对象(引用)调用子类独有的方法
  5. 引用类型转换
    1)向上类型转换(隐式/自动类型转换),是小类型到大类型的转换
    2)向下类型转换(强制类型转换),是大类型到小类型
    3)3)instanceof运算符可用来解决引用对象的类型,避免类型转换的安全性问题。在写程序时,如果想进行类型转换,为了避免程序的安全性问题,最好使用instanceof关键字来进行验证。
  6. Java中的抽象类
    · 定义:抽象类使用前使用abstract关键字修饰,则该类为抽象类。
    · 应用场景:
    1)在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
    2)从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。
    · 作用:限制规定子类必须实现某些方法,但不关注实现细节。
    · 使用规则:
    1)abstract定义抽象方法时,只有声明,不需要实现,因此其没有方法体,需要使用分号作为结束符号。
    2)包含抽象方法的类称为抽象类。
    3)抽象类中可以包含普通的方法,也可以没有抽象方法。
    4)抽象类不能直接创建,可以定义引用变量。
  7. Java中的接口
    · 概念:接口可以理解为一种特殊的类,由全局常量和公共的抽象方法所组成。类是一种具体实现体,而接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类里必须提供某些方法。
    · 定义:使用interface关键字
    · 接口就是用来被继承、被实现的,修饰符一般建议用public。注意:不能使用private和protected修饰接口。
    · 接口中的属性是常量,即使定义时不添加public static final修饰符,系统也会自动加上。
    · 接口中的方法只能是抽象方法,即使定义时不添加public abstract修饰符,系统也会自动加上。
    · 基本语法:
[修饰符] [abstract] interface 接口名 [extends 父接口1, 父接口2...]
            {
    零个到多个常量定义...
    零个到多个抽象方法的定义...
}

· 使用接口:一个类可以实现一个或多个接口,实现接口使用implements关键字。Java中一个类只能继承一个父类,是不够灵活的,通过实现多个接口可以做补充。同时,接口还经常和匿名内部类配合使用。匿名内部类就是没有名字的内部类,多用于关注实现而不关注实现类的名称。注意结尾要有分号作为结束符号。如:

Interface i = new Interface(){
    ...
};

· 继承父类实现接口的语法为:

[修饰符] class 类名 extends 父类 implements 接口1,接口2...
{
    类体部分
}

如果要继承父类,继承父类必须在实现接口之前

补充

  1. float型变量赋值时需加f,否则默认浮点数是double型
  2. 静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收!
  3. 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。
  4. 在普通成员方法中,可以直接访问同类的非静态变量和静态变量。
  5. 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。
  6. 静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量
  7. 当程序中既有‘静态初始化块’,又有‘普通初始化块’,还有‘构造方法’的时候,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。
  8. Java语言在实现对类的封装中,getter/setter方法的方法名通常为:‘get’关键字+属性名,且属性名大写,如:getAge()
  9. 在定义包时,包名必须放在Java源程序的第一行,包名间可以使用“.”号隔开
  10. 系统中的包:
    1)java.(功能).(类)
    2)java.lang.(类) 包含java语言基础的类
    3)java.util.(类) 包含java语言中各种工具类
    4)java.io.(类) 包含输入、输出相关功能的类
  11. 可以通过“*”导入某个包下的所有文件,如:java.util.*;
  12. 在Eclipse编译器中自动生成getter/setter方法:点击菜单栏中的‘Source’或通过在代码编辑区点击鼠标右键,选择‘Source’,然后选择‘Generate Getter and Setters’,选择想要生成getter/setter方法的属性,并点击‘OK’按钮即可生成。
  13. 成员内部类的.class文件的命名规则为:外部类名$内部类名.class
  14. 外部类是不能直接使用内部类的成员和方法的,必须先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法。
  15. 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用外部类的类名.this关键字.外部类的成员变量
  16. 在Eclipse编译器中自动生成toString()方法:点击菜单栏中的‘Source’或通过在代码编辑区点击鼠标右键,选择‘Source,然后选择‘Generate toString()’,选择想要生成toString()方法的属性,并点击‘OK’按钮即可生成。
  17. 在Eclipse编译器中自动生成equals()方法:点击菜单栏中的‘Source’或通过在代码编辑区点击鼠标右键,选择‘Source’,然后选择‘Generate hashCode() and equals()’,选择想要生成equals()方法的属性,并点击‘OK’按钮即可生成。
  18. 子类必须要调用其父类的隐式构造器。所以当我们在父类中手动添加了一个含参构造器时,Java程序就不会自动为父类添加一个无参的构造器,而继承于它的子类就会报错!

答答租车的小程序

  1. 功能:
    · 展示所有可租车辆
    · 可让用户选择所租车的车型及租车量
    · 展示租车清单,包含:总金额、总载货量及其车型、总载人量及其车型
  2. 核心代码如下所示:
package com.imooc;
import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		/**
		 * 1)'rent_a_car'变量用于存储用户是否租车的数据
		 * 2)'number'变量用于存储用户想要租车的数量
		 * 3)'serial_number'变量用于存储用户租车的序号
		 * 4)'number_of_manned'变量用于存储总载人数
		 * 5)'number_of_laden_cargo'变量用于存储总载货数
		 * 6)'sum_of_price'变量用于存储租车总价格
		 * 7)'mannedCar_name'数组用于存储用户所选的载人汽车的名字
		 * 8)'laden_cargo_name'数组用于存储用户所选的载货汽车的名字
		 * 9)'day_of_rent'数组用于存储用户的租车天数
		 */
		int rent_a_car; // 用于存储用户是否租车的数据
		int number;  // 用于存储用户想要租车的数量
		int serial_number;  // 用于存储用户租车的序号
		int number_of_manned = 0;  // 用于存储总载人数
		double number_of_laden_cargo = 0;  // 用于存储总载货数
		double sum_of_price = 0;  // 用于存储租车总价格
		String [] mannedCar_name;  // 用于存储用户所选的载人汽车的名字
		String [] laden_cargo_name;  // 用于存储用户所选的载货汽车的名字
		int day_of_rent;  // 用于存储用户的租车天数
		
		/**
		 * 生成六种汽车的实例对象,并在构造方法中进行初始化
		 */
		MannedCar Audi = new MannedCar("奥迪A4", 500, 4);
		MannedCar Mazda = new MannedCar("马自达6", 400, 4);
		Pickup Picca_snow = new Pickup("皮卡雪6", 450, 4, 2);
		MannedCar golden_dragon = new MannedCar("金龙", 800, 20);
		Truck Songhua_river = new Truck("松花江", 400, 4);
		Truck Iveco = new Truck("依维柯", 1000, 20);
		
		/**
		 * 给用户的一些提示信息
		 */
		System.out.println("欢迎使用答答租车系统:");
		System.out.println("您是否要租车: 1是 0否");
		
		/**
		 * 对'Scanner'类进行实例化
		 */
		Scanner input = new Scanner(System.in);
		
		// 将用户输入的是否要租车的信息存入'rent_a_car'变量中
		rent_a_car = input.nextInt();
		
		// 对用户输入的是否要租车的信息进行判断
		if(rent_a_car == 1){
			/**
			 * 给用户的一些提示信息——租车的类型及其价目表 
			 */
			System.out.println("您可租车的类型及其价目表:");
			System.out.println("序号\t汽车名称\t\t租金\t\t容量");
			System.out.println("1.\t奥迪A4\t\t500元/天\t\t载人:4人");
			System.out.println("2.\t马自达6\t\t400元/天\t\t载人:4人");
			System.out.println("3.\t皮卡雪6\t\t450元/天\t\t载人:4人 载货2吨");
			System.out.println("4.\t金龙\t\t800元/天\t\t载人:20人");
			System.out.println("5.\t松花江\t\t400元/天\t\t载货:4吨");
			System.out.println("6.\t依维柯\t\t1000元/天\t载货:20吨");
			System.out.println("请输入您要租汽车的数量:");
			
			// 1)将用户输入的要租汽车的数量信息存入'number'变量中
			// 2)同时在内存中分配(开辟)两份存储空间,每份number个存储空间
			// 3)一份存储载人汽车的汽车名称,一份存储载货汽车的汽车名称
			number = input.nextInt();
			mannedCar_name = new String[number];
			laden_cargo_name = new String[number];
			
			// 对用户输入的'number'变量进行for循环遍历
			for(int i = 1; i <= number; i++){
				// 每一次循环让用户输入第i辆车的序号,并将序号存储进'serial_number'变量中
				System.out.println("请输入第" + i + "俩车的序号:");
				serial_number = input.nextInt();
				
				/**
				 * · 对用户输入的第i俩车的序号进行判断
				 * · 一共要进行六次判断
				 */
				if(serial_number == 1){
					mannedCar_name[i-1] = Audi.car_name;
					number_of_manned += Audi.manned_capacity;
					sum_of_price += Audi.rent;
				}
				
				if(serial_number == 2){
					mannedCar_name[i-1] = Mazda.car_name;
					number_of_manned += Mazda.manned_capacity;
					sum_of_price += Mazda.rent;
				}
				
				if(serial_number == 3){
					mannedCar_name[i-1] = Picca_snow.car_name;
					laden_cargo_name[i-1] = Picca_snow.car_name;
					number_of_manned += Picca_snow.manned_capacity;
					number_of_laden_cargo += Picca_snow.freight_volume;
					sum_of_price += Picca_snow.rent;
				}
				
				if(serial_number == 4){
					mannedCar_name[i-1] = golden_dragon.car_name;
					number_of_manned += golden_dragon.manned_capacity;
					sum_of_price += golden_dragon.rent;
				}
				
				if(serial_number == 5){
					laden_cargo_name[i-1] = Songhua_river.car_name;
					number_of_laden_cargo += Songhua_river.freight_volume;
					sum_of_price += Songhua_river.rent;
				}
				
				if(serial_number == 6){
					laden_cargo_name[i-1] = Iveco.car_name;
					number_of_laden_cargo += Iveco.freight_volume;
					sum_of_price += Iveco.rent;
				}
			}
			
			// · 用于提示用户输入租车天数,并将用户输入的信息存储进'day_of_rent'变量中
			// · 并将其与'sum_of_price'变量的值相乘得出“租车总价格”
			System.out.println("请输入租车天数:");
			day_of_rent = input.nextInt();
			sum_of_price *= day_of_rent;
			
			// 将计算结果反馈(展现)给用户
			System.out.println("您的账单:");
			System.out.println("***可载人的车有:");
			
			/**
			 * 使用for循环遍历mannedCar_name[number]数组里面的数据
			 */
			for(int i = 0; i < mannedCar_name.length; i++){
				// 当mannedCar_name[i]里面的数据为空时,跳过此次循环,即:不将本次结果展现给用户
				if(mannedCar_name[i] == null){
					continue;
				}
				System.out.print("\t" + mannedCar_name[i]);
			}
			
			// 将载人汽车总的载人人数展示给用户
			System.out.println("\t共载人:" + number_of_manned + "人");
			
			System.out.println("***载货的车有:");
			/**
			 * 使用for循环遍历laden_cargo_name[number]数组里面的数据
			 */
			for(int i = 0; i < laden_cargo_name.length; i++){
				// 当laden_cargo_name[i]里面的数据为空时,跳过此次循环,即:不将本次结果展现给用户
				if(laden_cargo_name[i] == null){
					continue;
				}
				System.out.print("\t" + laden_cargo_name[i]);
			}
			// 将载货汽车总的载货货数展示给用户
			System.out.println("\t共载货:" + number_of_laden_cargo + "吨");
			
			// 将租车总价格展示给用户
			System.out.println("***租车总价格:" + sum_of_price + "元");
			
		}else{
			System.out.println("See you next time");
		}
	}

}

  1. 程序运行结果如下:
欢迎使用答答租车系统:
您是否要租车: 1是 0否
1
您可租车的类型及其价目表:
序号	汽车名称		租金		容量
1.	奥迪A4		500元/天		载人:4人
2.	马自达6		400元/天		载人:4人
3.	皮卡雪6		450元/天		载人:4人 载货2吨
4.	金龙		800元/天		载人:20人
5.	松花江		400元/天		载货:4吨
6.	依维柯		1000元/天	载货:20吨
请输入您要租汽车的数量:
3
请输入第1俩车的序号:
3
请输入第2俩车的序号:
6
请输入第3俩车的序号:
4
请输入租车天数:
10
您的账单:
***可载人的车有:
	皮卡雪6	金龙	共载人:24人
***载货的车有:
	皮卡雪6	依维柯	共载货:22.0吨
***租车总价格:22500.0元

猜你喜欢

转载自blog.csdn.net/chenlintao_csdn/article/details/87282564