147
社区成员
发帖
与我相关
我的任务
分享1. 梳理总结学习过的知识点(自行总结,内容不限于下列)
1.1 数据类型、表达式
数据类型包括基本类型和应用类型
整数类型:byte类型、short类型、int类型、long类型
浮点类型:float类型、double类型
(这两类字符类型可以通过(强转类型)变量名 来强制转化)
字符类型:
char是一个单一的 16 位 Unicode 字符
• 最小值是 \u0000(即为0);
• 最大值是 \uffff(即为65,535);
• char 数据类型可以储存任何字符;
布尔类型:boolean
二进制的原码、反码和补码
原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
正数
首位表示符号位,原码、反码和补码都是本身。
负数
如何计算负数在计算机中的二进制(即它的补码)?
首先对负数的绝对值取反,然后+1得到负数的补码。
运算符与表达式:
1.2 程序结构
循序语句:
即执行完第一行,执行第二行直到最后一行
条件语句:
主要有if语句和switch语句
If语句([ ]为可选部分):
If(条件){
语句1;
}[else{
语句2;
}]
二选一if条件语句:
If(条件){
语句1;
}else{
语句2;
}
多选一if条件语句:
If(条件1){
If(条件2){
语句1;
}else{
语句2;
}
}else if(条件3){
语句3;
}else{
语句4;
}
Switch语句([ ]为可选部分):
Switch(表达式)
{
Case值1:{语句体1;[break;]}
Case值2:{语句体2;[break;]}
……
Case值n:{语句体n;[break;]}
[default:{缺省语句体;}]
}
特殊的分支语句:
Switch(表达式)
{
Case值1:
Case值2:
Case值3:{语句体3;[break;]}
……
Case值n:{语句体n;[break;]}
[default:{缺省语句;}]
}
循环语句:
While循环语句(当条件恒满足时即while(true) 则陷入死循环):
While(条件){
循环体语句;
循环变量的迭代;
}
Do-while循环语句(当条件恒满足时即while(true) 则陷入死循环):
初始化部分;
Do{
循环体语句;
[迭代部分;]
}while(条件);
For循环(当for( ; ; ) 即没有条件或恒满足陷入死循环):
For(表达式1;表达式2;表达式3){
循环体语句;
}
1.3 数组应用
数组
3.1.1定义:数组是可以保存一组数据的一种数据结构,它本身也会占用一个内存地址,因此数组是引用类型。
声明:数组类型 数组名 [] 或数组类型 [] 数组名;
3.1.2静态初始化
静态数组化指在一开始就有所定义;
主要有以下方法:
int []arr;
int [] arr={1,2,3,4,5};
3.1.3动态初始化
动态数组可通过输入端输入数组;
int [] arr=new int [n]//n为字符长度;
3.1.4数组的应用
3.1.4.1访问数组
可以在数组长度内访问其中的数值;
3.1.4.2数组遍历
可以通过for循环来访问遍历数组的元素;
如:int []arr=new int [n]
For(int i=0;i<arr.length;i++){
}
3.1.5.1数组最大值和最小值
首先把数组的第一个数赋值给变量max和min,分别表示最大值和最小值,再依次判断数组的其他数值的大小,判断当前值是否最大值或最小值,如果不是则进行替换,最后输出最大值和最小值。
3.1.5.2数组排序
其中最简单的方法为冒泡排序
for(j = 0; j <arr.length-1; j ++) {
for(i = 0; i <arr.length-1-j; i++) {
if(a[i] > a[i+1]) {
t = a[i];
a[i] = a[i+1];
a[i+1] = t;
}
}
}
3.1.5.3数组的内存原理
数组是引用数据类型,因此数组变量就是一个引用变量,通常被存储在栈(Stack)内存中。数组初始化后,数组对象被存储在堆(Heap)内存中的连续内存空间,而数组变量存储了数组对象的首地址,指向堆内存中的数组对象。接下来演示一维数组在内存中的存储原理。
3.2二维数组
二维数组可以看成以数组为元素的数组,常用来表示表格或矩形。二维数组的声明、初始化与一维数组类似。
3.2.1二维数组的建立的方法:
Int [] []arr;
Int arr [] [];
静态数组:
Int arr=new int [][]{{1},{2,3},{4}};
动态初始化:
Int arr [] [] =new int [2][3]//2,3分别为一维跟二维的长度;
运用:冒泡排序
将数组元素从小到大排序
import java.util.Scanner;
class Main{
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
final int N = 6;
int i, j, t;
int [] a = new int[N];
for(i = 0; i < a.length; i++){
a[i] = (int)(Math.random()*10);
}
//输出数据
for(i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
for(j = 0; j < a.length ; j ++) {
//第j趟中,
for(i = 0; i <(a.length-1) - j; i++) {
if(a[i] > a[i+1]) {
t = a[i]; a[i] = a[i+1]; a[i+1] = t;
}
}
}
System.out.println("The sorted numbers:");
for(i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
sc.close();
}
}
二维数组的运用:
运用二维数组输出等腰直角三角形;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
String [][]arr=new String [n][n];
for(int i=0;i<arr.length;i++){
for(int j=0;j<=i;j++){
arr[i][j]="*";
}
}
for(int i=0;i<arr.length;i++){
for(int j=0;j<=i;j++){
System.out.print(arr[i][j]);
}
System.out.println();
}
sc.close();
}
}
1.4 类、方法
在程序开发初期人们使用结构化开发语言,但随着软件的规模越来越大,结构化语言的弊端也逐渐暴露出来,开发周期被延长,产品的质量也不尽人意,结构化语言已经不再适合当前的软件开发。这时人们开始将另一种开发思想引入程序中,即面向对象的开发思想。面向对象思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,同时了解这些对象具有哪些相应的属性以及展示这些对象的行为,以解决这些对象面临的一些实际问题,这样就在程序开发中引入了面向对象设计的概念,面向对象设计实际上就是对现实世界的对象进行建模操作。面向对象的特点主要可以概括为封装性、继承性和多态性,接下来针对这三种特性进行简单介绍。
封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。例如,用户使用计算机时,只需要使用手指敲击键盘就可以实现一些功能,无须知道计算机内部是如何工作的,即使知道计算机的工作原理,在使用计算机时也并不完全依赖于计算机工作原理这些细节。
类与类之间同样具有关系,如一个百货公司类与销售员类相联系,类之间的这种关系被称为关联。关联主要描述两个类之间的一般二元关系,例如,一个百货公司类与销售员类就是一个关联,学生类与教师类也是一个关联。两个类之间的关系有很多种,继承是其中的一种。
多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类及相关类。该统一风格可以由父类来实现,根据父类统一风格的处理,可以实例化子类的对象。由于整个事件的处理都只依赖于父类的方法,所以日后只要维护和调整父类的方法即可。这样就降低了维护的难度,节省了时间。
类实质上就是封装对象属性和行为的载体,而对象则是类抽象出来的一个实例。
在类中,属性是通过成员变量体现的,而行为是成员函数(又称为方法)实现的,下面为大家演示Java中定义类的通用格式,其语法格式如下:
class 类名{
属性类型 成员变量名; // 成员变量(对象属性)
…
修饰符 返回值类型 方法名([参数列表]) { // 成员方法(对象行为)
// 方法体
return 返回值;
}
}
类是对象的抽象,为对象定义了属性和行为,但类本身既不带任何数据,也不存在于内存空间中。而对象是类的一个具体存在,既拥有独立的内存空间,也存在独特的属性和行为,属性还可以随着自身的行为而发生改变。接下来演示如何用类创建对象,创建对象之前,必须先声明对象,其语法格式如下:
类名 对象名;
类是自定义类型,也是一种引用类型,因此该对象名是一个引用变量,默认值为null,表示不指向任何堆内存空间。接下来需要对该变量进行初始化,Java使用new关键字来创建对象,也称实例化对象,其语法格式如下:
对象名 = new 类名();
对象实例化后,就可以访问对象的成员变量和成员方法,其语法格式如下:
对象名.成员变量;
对象名.成员方法();
封装是面向对象的三大特征之一,类的设计者将类设计成一个黑匣子,使用者只能通过类所提供的公共方法来实现对内部成员的操作和访问,而不能看见方法的实现细节,也不能直接访问对象内部成员。类的封装可以隐藏类的实现细节,迫使用户只能通过方法去访问数据,这样就可以增强程序的安全性。
如果想改变默认的初始化,让系统创建对象时就为该对象的成员属性显式地指定初始值,可以通过构造方法来实现。构造方法是类中一个特殊的成员方法,用于为类中属性初始化。
构造方法是在创建一个对象使用new关键字时被调用的。构造方法有三个特征:
如果类未定义任何构造方法,系统会自动提供一个默认构造方法,又称缺省构造方法。如果已存在带参数的构造方法,则系统将不会提供缺省构造方法。
每次定义类的构造方法时,应预先定义一个无参的构造方法,有参的构造方法可以根据需求再定义。
由于系统提供的默认构造方法通常不能满足需求,这时就需要多个构造方法,与普通方法一样,只要每个构造方法的参数列表不同,即可实现重载。这样在创建对象时,就可以通过调用不同的构造方法为不同的属性赋值。
类在定义成员方法时,局部变量和成员变量可以重名,但此时不能访问成员变量。为避免这种情形,Java提供了this关键字,表示当前对象,指向调用的对象本身。
this关键字可以明确调用类的成员变量,不会与局部变量名发生冲突。
this既然可以访问成员变量,那么也可以访问成员方法。
构造方法是在实例化时被自动调用的,因此不能直接像调用成员方法一样去调用构造方法,但可以使用this([实参列表])的方式调用其他的构造方法。
在使用this调用构造方法时,还需注意:在构造方法中,使用 this调用构造方法的语句必须位于首行,且只能出现一次。
另外,this调用构造方法时,一定要留一个构造方法作为出口,即至少存在一个构造方法不使用this调用其他构造方法。
在Java中,用new关键字创建对象或数组等引用类型时,都会在堆内存中为之分配一块内存,用于保存对象,当此块内存不再被任何引用变量引用时,这块内存就变成垃圾。Java引入了垃圾回收机制(Garbage Collection,GC)来处理垃圾,它是一种动态存储管理技术,由Java虚拟机自动回收垃圾对象所占的内存空间,不需要程序代码来显式释放。
当一个对象失去引用时,除了等待Java虚拟机自动回收之外,还可以调用System.gc()方法来通知Java虚拟机进行垃圾回收。该方法只是向Java虚拟机发出一个回收申请,至于Java虚拟机是否进行垃圾回收并不能确定。
当一个对象在内存中被释放时,Java虚拟机会自动调用该对象的finalize()方法,该方法用于在对象被垃圾回收机制销毁前执行一些资源回收工作。如果在程序终止前Java虚拟机始终没有执行垃圾回收操作,那么Java虚拟机将始终不会调用该对象的finalize()方法。在Java的祖先类中提供了finalize()方法,因此,所有的类都可以重写该方法,但需注意该方法没有任何参数和返回值,并且每个类中有且只有一个该方法。
static关键字表示静态的,用于修饰成员变量、成员方法以及代码块,如用static修饰main()方法。灵活正确地运用static关键字,可以使程序更符合现实世界逻辑。
使用static修饰的成员变量,称为静态变量或类变量,它被类的所有对象共享,属于整个类所有,因此可以通过类名直接来访问。而未使用static修饰的成员变量称为实例变量,它属于具体对象独有,只能通过引用变量访问。
使用static修饰的成员方法,称为静态方法,无须创建类的实例就可以调用静态方法,静态方法可以通过类名调用。
静态方法只能访问类的静态成员(静态变量、静态方法),不能访问类中的实例成员(实例变量和实例方法)。这是因为未被static修饰的成员都是属于对象的,所以需要先创建对象才能访问,而静态方法在被调用时可以不创建任何对象。
代码块是指用大括号“{}”括起来的一段代码,根据位置及声明关键字的不同,代码块可分为普通代码块、构造代码块、静态代码块和同步代码块,其中同步代码块在第7章进行讲解。
普通代码块就是在方法名后或方法体内用大括号“{}”括起来的一段代码。
构造代码块就是直接定义在类中的代码块,它没有任何前缀、后缀及关键字修饰。上节中提到,每个类中至少有一个构造方法,创建对象时,构造方法被自动调用,构造代码块也是在创建对象时被调用,但它在构造方法之前被调用,因此,构造代码块也可用来初始化成员变量。
静态代码块就是使用static关键字修饰的代码块,它是最早执行的代码块。
设计模式描述了软件设计过程中经常碰到的问题及解决方案,它是面向对象设计经验的总结和理论化抽象。通过设计模式,开发者就可以无数次地重用已有的解决方案,无需再重复相同的工作。
单例模式是设计模式中的一种,是指一个类在程序运行期间有且仅有一个实例,并且自行实例化向整个系统提供这个实例。例如Windows操作系统只提供一个任务管理器。单例类的一个重要特征是类的构造方法是私有的,从而避免了外部利用构造方法直接创建多个实例。
单例模式有3个特点,具体如下:
在Java中,类中除了可以定义成员变量与成员方法外,还可以定义类,该类称作内部类,内部类所在的类称作外部类。根据内部类的位置、修饰符和定义的方式可分为成员内部类、静态内部类、方法内部类以及匿名内部类4种。
内部类有3点共性:
私有成员),但外部类不能直接访问内部类成员。
public 和默认的访问权限。
成员内部类是指类作为外部类的一个成员,能直接访问外部类的所有成员,但在外部类中访问内部类,则需要在外部类中创建内部类的对象,使用内部类的对象来访问内部类中的成员。同时,若要在外部类外要访问内部类,则需要通过外部类对象去创建内部类对象,在外部类外创建一个内部类对象的语法格式如下:
外部类名.内部类名 引用变量名=new 外部类名().new 内部类名()
需要注意的是,成员内部类不能定义静态变量、静态方法和静态内部类。这是因为当外部类被加载时,内部类是非静态的,那么Java编译器就不会初始化内部类中的静态成员,这就与Java编译原则相违背。
如果不需要外部类对象与内部类对象之间有联系,那么可以将内部类声明为static,用static关键字修饰的内部类称为静态内部类。静态内部类可以有实例成员和静态成员,它可以直接访问外部类的静态成员,但如果想访问外部类的实例成员,就必须通过外部类的对象去访问。另外,如果在外部类外访问静态内部类成员,则不需要创建外部类对象,只需创建内部类对象即可。创建内部类对象的语法格式如下:
外部类名.内部类名 引用变量名=new 外部类名.内部类名()
若访问内部类的静态成员,则无须创建外部类和静态内部类对象,通过“外部类名.内部类名.静态成员”的形式访问。要访问内部类的实例成员,则需要创建静态内部类对象,通过“new 外部类名.内部类名()”形式直接创建内部类对象。
方法内部类是指在成员方法中定义的类,它与局部变量类似,作用域为定义它的代码块,因此它只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
匿名内部类就是没有名称的内部类。创建匿名内部类时会立即创建一个该类的对象,该类定义立即消失,匿名内部类不能重复使用。
需要注意的是,匿名内部类是不能加访问修饰符的,而且被new的匿名类必须是先定义的。
继承是面向对象的另一大特征,它用于描述了类的所属关系,多个类通过继承形成一个关系体系。继承是在原有类的基础上扩展新的功能,实现了代码的复用。
在现实生活中,继承是指下一代人继承上一代人遗留的财产,即实现财产重用。在面向对象程序设计中,继承实现代码重用,即在已有类的基础上定义新的类,新的类能继承已有类的属性与行为,并扩展新的功能,而不需要把已有类的内容再写一遍。已有的类被称为父类或基类,新的类被称为子类或派生类。例如交通工具与公交车就属于继承关系,公交车拥有交通工具的一切属性,但同时又拥有自己独有的特性。在Java中,子类继承父类的语法格式如下:
class 子类名 extends 父类名 {
属性和方法
}
Java使用extends关键字指明两个类之间的继承关系。子类继承了父类中的属性和方法,也可以添加新的属性和方法。
Java语言只支持单继承,不允许多重继承,即一个子类只能继承一个父类,否则会引起编译错误,具体示例如下:
class A {}
class B {}
class C extends A, B {}
Java语言虽然不支持多重继承,但它支持多层继承,即一个类的父类可以继承另外的父类。因此,Java类可以有无限多个间接父类,具体示例如下:
class A {}
class B extends A {}
class C extends B {}
在继承关系中,子类从父类中继承了可访问的方法,但有时从父类继承下来的方法不能完全满足子类需要,如果要求父类与子类中的方法输出不同内容,这时就需要在子类的方法里修改父类的方法,即子类重新定义从父类中继承的成员方法,这个过程称为方法重写或覆盖。在进行方法重写时必须考虑权限,即被子类重写的方法不能拥有比父类方法更加严格的访问权限。
另外,需要注意方法重载与方法重写的区别:
当子类重写父类方法后,子类对象将无法访问父类被重写的方法。如果在子类中需要访问父类的被重写方法,可以通过super关键字来实现,其语法格式如下:
super.成员变量
super.成员方法([实参列表])
在继承中,实例化子类对象时,首先会调用父类的构造方法,再调用子类的构造方法,这与实际生活中先有父母再有孩子类似。子类继承父类时,并没有继承父类的构造方法,但子类构造方法可以调用父类的构造方法。在一个构造方法中调用另一个重载的构造方法使用this关键字,在子类构造方法中调用父类的构造方法用super关键字,其语法格式如下:
super([参数列表])
在Java中,为了考虑安全因素,要求某些类不允许被继承或不允许被子类修改,这时可以用final关键字修饰。它可用于修饰类、方法和变量,表示“最终”的意思,即用它修饰的类、方法和变量不可改变,具体特点如下:
使用final关键字修饰的类称为最终类,表示不能再被其他的类继承,如Java中的String类。
使用final关键字修饰的方法,称为最终方法,表示子类不能重写此方法。
使用final关键字修饰的变量,称为常量,只能被赋值一次。如果再次对该变量进行赋值,则程序在编译时会报错。
Java中可以定义不含方法体的方法,方法的方法体由该类的子类根据实际需求去实现,这样的方法称为抽象方法(abstract method),包含抽象方法的类必须是抽象类(abstract class)。
Java中提供了abstract关键字,表示抽象的意思。用abstract修饰的方法,称为抽象方法,是一个不完整的方法,只有方法的声明,没有方法体。用abstract修饰的类,称为抽象类,抽象类可以不包含任何抽象方法,具体示例如下:
// 用abstract修饰抽象类
abstract class Parent {
// abstract修饰抽象方法,只有声明,没有实现
public abstract void say();
}
使用抽象类时需要注意,抽象类不能被实例化,即不能用new关键字创建对象,因为抽象类中可包含抽象方法,抽象方法只有声明,没有方法体,不能被调用。因此,必须通过子类继承抽象类去实现抽象方法。
需要注意的是,具体子类必须实现抽象父类中所有抽象方法,否则子类必须声明为抽象类。
另外,抽象方法不能用static来修饰,因为static修饰的方法可以通过类名调用,调用时将调用一个没有方法体的方法,肯定会出错;抽象方法也不能用final关键字修饰,因为被final关键字修饰的方法不能被重写,而抽象方法的实现需要在子类中实现;抽象方法也不能用private关键字修饰,因为子类不能访问带private关键字的抽象方法。
抽象类中可以定义构造方法,因为抽象类仍然使用的是类继承关系,而且抽象类中也可以定义成员变量。因此,子类在实例化时必须先对抽象类进行实例化。
接口是全局常量和公共抽象方法的集合,接口可被看作一种特殊的类,也属于引用类型。每个接口都被编译成独立的字节码文件。Java提供interface关键字,用于声明接口,其语法格式如下:
interface 接口名{
全局常量声明
抽象方法声明
}
接下来演示interface关键字的作用,具体示例如下:
// 用interface声明接口
interface Parent {
String name;// 等价public static final String name;
void say(); // 等价public abstract void say();
}
接口中定义的变量和方法都包含默认的修饰符,其中定义的变量默认声明为“public static final”,即全局常量。另外定义的方法默认声明为“public abstract”,即抽象方法。
与抽象类相似,接口中也包含抽象方法。因此,不能直接实例化接口,即不能使用new创建接口的实例。Java提供implements关键字,用于实现多个接口,其语法格式如下:
class 类名 implements 接口列表{
属性和方法
}
在Java中使用extends关键字来实现接口的继承,它与类的继承类似,当一个接口继承父接口时,该接口会获得父接口中定义的所有抽象方法和常量;但又与类的继承不同,接口支持多重继承,即一个接口可以继承多个父接口。其语法格式如下:
interface 接口名 extends 接口列表 {
全局常量声明
抽象方法声明
}
需要特别指出的是,任何实现继承接口的类,必须实现该接口继承的其他接口,除非类被声明为abstract。
抽象类与接口是Java语言中对于抽象类定义进行支持的两种机制,两者非常相似,初学者经常混淆这两个概念,两者的相同点可以归纳为三点:
下表列出了两者之间的区别,如表6.1所示。
|
区别点 |
接口 |
抽象类 |
|
含义 |
接口通常用于描述一个类的外围能力,而不是核心特征。类与接口之间的是-able或者can do的关系。 |
抽象类定义了它的后代的核心特征。派生类与抽象类之间是is-a的关系。 |
|
方法 |
接口只提供方法声明。 |
抽象类可以提供完整方法、缺省构造方法以及用于覆盖的方法声明。 |
|
变量 |
只包含public static final常量,常量必须在声明时初始化。 |
可以包含实例变量和静态变量。 |
|
多重继承 |
一个类可以继承多个接口。 |
一个类只能继承一个抽象类。 |
|
实现类 |
类可以实现多个接口。 |
类只从抽象类派生,必须重写。 |
|
适用性 |
所有的实现只是共享方法签名。 |
所有实现大同小异,并且共享状态和行为。 |
|
简洁性 |
接口中的常量都被默认为public static final,可以省略。接口中的方法被默认为public abstract。 |
可以在抽象类中放置共享代码。必须用abstract显式声明方法为抽象方法。 |
|
添加功能 |
如果为接口添加一个新的方法,则必须查找所有实现该接口的类,并为它们逐一提供该方法的实现。 |
如果为抽象类提供一个方法,可以选择提供一个缺省的实现,那么所有已存在的代码不需要修改就可以继续工作。 |
总体来说,抽象类和接口都用于为对象定义共同的行为,两者在很大程度上是可以互相替换的,但由于抽象类只允许单继承,所以当两者都可以使用时,优先考虑接口,只有当需要定义子类的行为,并为子类提供共性功能时才考虑选用抽象类。
多态是面向对象的另一大特征,封装和继承是为实现多态做准备的。简单来说,多态是具有表现多种形态的能力的特征,它可以提高程序的抽象程度和简洁性,最大程度降低了类和程序模块间的耦合性。
多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在Java程序中,多态是指把类中具有相似功能的不同方法使用同一个方法名实现,从而可以使用相同的方式来调用这些具有不同功能的同名方法。
Java中的引用变量有两种类型,即声明类型和实际类型。变量声明时被指定的类型称为声明类型,而被变量引用的对象类型称为实际类型。方法可以在沿着继承链的多个类中实现,当调用实例方法时,由Java虚拟机动态地决定所调用的方法,称为动态绑定。
动态绑定机制原理是:当调用实例方法时,Java虚拟机从该变量的实际类型开始,沿着继承链向上查找该方法的实现,直到找到为止,并调用首次找到的实现。
对象的类型转换是指可以将一个对象的类型转换成继承结构中的另一种类型。类型转换分为两种,具体如下:
需要特别注意的是,向下转型时,被转换变量的实际类型,必须是转换类或其子类。
Java提供了instanceof关键字,用于判断一个对象是否是一个类(或接口)的实例,表达式返回boolean值,其语法格式如下:
变量名 instanceof 类名
Java中提供了一个Object类,是所有类的父类,如果一个类没有显式地指定继承类,则该类的父类默认为Object。例如,下面两个类的定义是一样的:
class ClassName {}
class ClassName extends Object {}
在Object类中提供了很多方法,接下来分别对其中的方法进行解释,如表6.2所示。
|
方法声明 |
功能描述 |
|
public String toString() |
返回描述该对象的字符串 |
|
public Boolean equals(Object o) |
比较两个对象是否相等 |
|
public int hashCode() |
返回对象的哈希值 |
暂时只对toString()和equals方法进行讲解,而hashCode()方法在Java集合中再详细讲解。
调用一个对象的toString()方法会默认返回一个描述该对象的字符串,它由该对象所属类名、@和对象十六进制形式的内存地址组成。
通常,重写toString()方法返回对象具体的信息。
equals()方法是用于测试两个对象是否相等。
如果要检测两个不同对象的内容是否相同,就必须重写equals()方法。例如String类中的equals()方法继承自Object类并重写,使之能够检验两个字符串的内容是否相等。
工厂模式主要用来实例化有共同接口的类,它可以动态决定应该实例化哪一个类,不必事先知道每次要实例化哪一个类。工厂模式主要有三种形态:简单工厂模式、工厂方法模式和抽象工厂模式。接下来分别对这三种形态进行讲解。
简单工厂模式又称静态工厂方法,它的核心是类中包含一个静态方法,该方法用于根据参数来决定返回实现同一接口不同类的实例。
工厂类SimpleFactory有很多局限。首先,维护和新增产品时,都必须修改SimpleFactory源代码。其次,如果产品之间存在复杂的层次关系,则工厂类必须拥有复杂的逻辑判断。最后,整个系统都依赖SimpleFactory类,一旦SimpleFactory类出现问题,整个系统就将瘫痪不能运行。
工厂方法模式为工厂类定义了接口,用多态来削弱了工厂类的职责。
工厂方法模式也有局限之处,当面对有复杂的树形结构的产品时,就必须为每个产品创建一个对应的工厂类,当达到一定数量级就会出现类爆炸。
抽象工厂用于创建一系列互相关联或互相依赖的对象。
代理模式是指给某一个对象提供一个代理,并由代理对象控制对原有对象的引用。如生活中,求职者找工作(真实操作),可以让猎头帮忙去找(代理操作),猎头把最终结果反馈给求职者。无论是真实操作还是代理操作,目的都是一样的,求职者只关心最终结果,而不关心过程。
当声明的类很多时,类名就有可能冲突,这就需要一种机制来管理类名,因此,Java中引入了包机制,本节将详细介绍包的用法。
包(package)是Java提供的一种区别类的名字空间的机制,是类的组织方式,是一组相关类和接口的集合,它提供了访问权限和命名的管理机制。
使用package语句声明包,其语法格式如下:
package 包名
使用时需要注意以下四点:
包与文件目录类似,可以分成多级,多级之间用“.”符号进行分隔,具体示例如下:
package com.l000phone.www;
如果在程序中已声明了包,就必须将编译生成的字节码文件保存到与包名同名的子目录中,可以使用带包编译命令,具体示例如下:
javac -d . Source.java
其中,“-d”表示生成以package定义为准的目录,“.”表示在当前所在的文件夹中生成。编译器会自动在当前目录下建立与包名同名的子目录,并将生成的.class文件自动保存到与包名同名的子目录下。
接下来分步骤讲解包机制管理Java源文件:
(1)在源文件首行声明包。
(2)使用“javac -d . TestPackage.java”编译源文件。
(3)执行命令完成后,在当前目录下会生成包名对应的目录。
(4)使用“java com.l000phone.www.TestPackage”命令运行程序,运行带包名的字节码文件时,必须输入完整的“包.类名称”。
在实际开发中,项目都是分模块开发,对应模块包中的类,完成相应模块的功能。但有时模块之间的类要相互调用。例如,通常开发中都是将业务逻辑层的接口和实现放在不同包中。
为了简化编程,Java提供了import关键字,用于导入指定包层次下某个类或全部类,import语句应放在package语句之后,类定义之前,其语法格式如下:
import 包名.类名 // 导入单类
import 包名.* // 导入包层次下的全部类
在JDK5.0后提供了静态导入功能,用于导入指定类的某个静态成员变量、方法或全部的静态成员变量、方法,具体示例如下:
import static 包名.类名.成员 // 导入类指定静态成员
import static 包名.类名.* // 导入该类全部静态成员
import语句和import static语句之间没有任何顺序要求。使用import导入包后,可以在代码中直接访问包中的类,即可以省略包名;而使用import static导入类后,可以在代码中直接访问类中静态成员,即可以省略类名。
Java的核心类都放在java包及其子包下,Java扩展的类都放在javax包及其子包下,接下来了解一下常用的开发包,如表6.3所示。
|
包名 |
功能描述 |
|
java.lang |
核心包,如String、Math、System类等,无需使用import手动导入,系统自动导入 |
|
java.util |
工具包,包含工具类、集合类等,如Arrays、List和Set等 |
|
java.net |
包含网络编程的类和接口 |
|
java.io |
包含输入、输出编程相关的类和接口 |
|
java.text |
包含格式化相关的类 |
|
java.sql |
数据库操作包,提供了各种数据库操作的类和接口 |
|
java.awt |
包含抽象窗口工具集(abstract window toolkits)相关类和接口,主要用于构建图形用户界面(GUI) |
|
java.swing |
包含图形用户界面相关类和接口 |
在实际开发中,通常会将一些类提供给别人使用,直接提供字节码文件会比较麻烦,所以一般会将这些类文件打包成jar文件,以供别人使用。jar文件的全称是Java Archive File,意思就是Java归档文件,也称为jar包。将一个jar包添加到classpath环境变量中,Java虚拟机会自动解压jar包,根据包名所对应的目录结构去查找所需的类。
通常使用jar命令来打包,可以把一个或多个路径压缩成一个jar文件。jar命令是在JDK安装目录下的bin目录中,直接在命令行中输入jar命令,即可查看jar命令的提示信息。
jar命令主要参数如下:
接下来分步骤学习如何用jar命令进行文件打包及运用jar包:
(1)打开命令行窗口,切换到将要被打包目录的上级目录,输入命令:
jar -cvf common.jar com
上面命令是将com目录下的全部内容打包成common.jar文件,如果硬盘上有同名jar将被覆盖。
(2)输入“set classpath=.;D:\com\1000phone\chapter05\05\common.jar”命令,将jar包添加到环境变量中。
(3)删除生成的包目录及User.class文件。编写测试类,测试jar包是否可用。
(4)查看jar包命令如下:
jar -tvf jar文件名
如查看common.jar文件,则输入命令“jar -tvf common.jar”。
(5)解压jar包命令如下:
jar -xvf jar文件名
如解压common.jar文件,则输入命令“jar -xvf common.jar”,参数x代表从归档中提取指定的文件。
有了包的概念之后,接下来将系统介绍Java中访问权限的概念。它可以对类、属性以及方法进行声明和控制,以便隐藏类的一些实现细节,防止对封装数据未经许可的访问和不合理的操作。
Java中的4种访问权限级别由小到大依次如下:
接下来总结4种访问控制权限,如表5.4所示。
|
访问范围 |
private |
default |
protected |
public |
|
同一类中成员 |
√ |
√ |
√ |
√ |
|
同一包中其他类 |
|
√ |
√ |
√ |
|
不同包中子类 |
|
|
√ |
√ |
|
不同包的非子类 |
|
|
|
√ |
2. PTA实践总结
选择不少于两个程序示例进行说明,需要发布源代码、测试用例。
谈一下在线刷题的个人感受。
2.1示例1
7-9 sdut-小I选宾馆
小 I 去北京旅游,要选一个宾馆住下。对于一个宾馆来说,有许多特征,比如「价格」、「舒适度」。
小I会对每个特征都有一个满意度。他将选择满意度更高一些的宾馆。「价格」对于小 I 来说是最重要的,其次是「舒适度」。如果对「价格」的满意度相同,那么根据「舒适度」进行选择;如果有多个宾馆条件相同,则输出编号最小的宾馆。
小 I 现在面对一堆宾馆不知所措,你能帮他找到最满意的宾馆吗?
多组输入,对于每组输入:
给出 n (n <= 5000) 代表 n 个宾馆(编号从 1 - n),随后有 n 行数据。
每行数据有两个整数,分别代表小I对「价格」、「舒适度」的满意程度,数值越大满意程度越高,满意度的范围从0 - 5000。
输出按照描述的条件中小I最满意的宾馆编号。如果有多个宾馆条件相同,输出编号最小的宾馆。
4
0 1
1 0
1 1
1 0
4
1 2
2 3
1 2
2 3
3
2
代码
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNextInt()){
int n=sc.nextInt();
int m=-1;
int c=-1;
int index=-1;
int [][]arr=new int [n][2];
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
arr [i][j]=sc.nextInt();
}
}
for(int j=n-1;j>=0;j--){
if(arr[j][0]>m){
m=arr[j][0];
}
}
for(int k=n-1;k>=0;k--){
if(arr[k][0]==m){
if(arr[k][1]>c){
c=arr[k][1];
index=k;
}
}
}
System.out.println(index+1);
}
}
}
这题是在数组应用中的最后一题,当时刚开始写起来感觉每个题都很难,可是后面通过层层突破最后写了出来。刚开始看到这个题时觉得任务太多有点应接不暇,一下子整个人都很慌,感觉有点迷茫不知如何下手,后面将任务拆解,解决,最后拼装。以一个二维数组录入数据,以为长度代表宾馆,二维长度代表评判标准。这题让我更加清晰的认识到做题的步骤,且也更精确的了解二维数组的运用。
2.2示例
2
7-3 通过键盘输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
统计一行字符串中的英文字母个数、空格个数、数字个数、其他字符个数
通过键盘输入一行字符(任意字符)
统计一行字符串中的英文字母个数、空格个数、数字个数、其他字符个数
rwrwewre2345asdJSJQI%^&(& *&sdf YY( 2342-k'
字母个数:22
数字个数:8
空格个数:5
其他字符个数:10
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
String str=sc.nextLine();
statistics(str);
}
public static void statistics(String str) {
int a=0;
int b=0;
int c=0;
int d=0;
char []arr=str.toCharArray();
for(int i=0;i<arr.length;i++){
if(arr[i]>='A'&&arr[i]<='Z'||arr[i]>='a'&&arr[i]<='z')
a++;
else if(arr[i]==' ')
c++;
else if(arr[i]>='0'&&arr[i]<='9')
b++;
else
d++;
}
System.out.println("字母个数"+":"+a);
System.out.println("数字个数"+":"+b);
System.out.println("空格个数"+":"+c);
System.out.println("其他字符个数"+":"+d);
}
}
这题是类的一题,这题的统计字符内容是之前写过的,我以为我能得心应手的处理好数据的统计跟录入。结果写的时候还是出现了不少的问题。这让我深刻的了解到对基础知识的复习跟运用的重要性。
2.5在线评测系统使用感受
还行,其中的评测可以对代码错误有及时的指出,对输出有明确的对比可以及时的更改。
3. 改进学习方法、措施落实情况(内容可扩展,至少包括以下项)
3.1 除课堂外,遇到不会的问题时会到哪个平台搜索
csdn
3.2 根据记录2个月的每天代码时长,利用excel绘制统计表
|
日期 |
代码时长(小时) |
累加代码时长 |
|
2022/9/26 |
0 |
0 |
|
2022/9/27 |
0 |
0 |
|
2022/9/28 |
0 |
0 |
|
2022/9/29 |
0 |
0 |
|
2022/9/30 |
0 |
0 |
|
2022/10/1 |
0 |
0 |
|
2022/10/2 |
0 |
0 |
|
2022/10/3 |
0 |
0 |
|
2022/10/4 |
0 |
0 |
|
2022/10/5 |
0 |
0 |
|
2022/10/6 |
4 |
4 |
|
2022/10/7 |
3 |
7 |
|
2022/10/8 |
3 |
10 |
|
2022/10/9 |
2 |
12 |
|
2022/10/10 |
2 |
14 |
|
2022/10/11 |
2 |
16 |
|
2022/10/12 |
1 |
17 |
|
2022/10/13 |
1 |
18 |
|
2022/10/14 |
3 |
21 |
|
2022/10/15 |
2 |
23 |
|
2022/10/16 |
3 |
26 |
|
2022/10/17 |
2 |
28 |
|
2022/10/18 |
5 |
33 |
|
2022/10/19 |
0 |
33 |
|
2022/10/20 |
2 |
35 |
|
2022/10/21 |
5 |
40 |
|
2022/10/22 |
5 |
45 |
|
2022/10/23 |
5 |
50 |
|
2022/10/24 |
2 |
52 |
|
2022/10/25 |
1.5 |
53.5 |
|
2022/10/26 |
1.5 |
55 |
|
2022/10/27 |
3 |
58 |
|
2022/10/28 |
3 |
61 |
|
2022/10/29 |
4 |
65 |
|
2022/10/30 |
2 |
67 |
|
2022/10/31 |
1 |
68 |
|
2022/11/1 |
2 |
70 |
|
2022/11/2 |
2 |
72 |
|
2022/11/3 |
3 |
75 |
|
2022/11/4 |
5 |
80 |
|
2022/11/5 |
5 |
85 |
|
2022/11/6 |
4 |
89 |
|
2022/11/7 |
1.5 |
90.5 |
|
2022/11/8 |
1.5 |
92 |
|
2022/11/9 |
1.5 |
93.5 |
|
2022/11/10 |
2 |
95.5 |
|
2022/11/11 |
5 |
100.5 |
|
2022/11/12 |
3 |
103.5 |
|
2022/11/13 |
3 |
106.5 |
|
2022/11/14 |
1.5 |
108 |
|
2022/11/15 |
1.5 |
109.5 |
|
2022/11/16 |
1.5 |
111 |
|
2022/11/17 |
2 |
113 |
|
2022/11/18 |
4 |
117 |
|
2022/11/19 |
5 |
122 |
|
2022/11/20 |
6 |
128 |
|
2022/11/21 |
1.5 |
129.5 |
|
2022/11/22 |
1.5 |
131 |
|
2022/11/23 |
1.5 |
132.5 |
|
2022/11/24 |
5 |
137.5 |
|
2022/11/25 |
5 |
142.5 |
|
2022/11/26 |
6 |
148.5 |
|
2022/11/27 |
3 |
151.5 |
|
2022/11/28 |
4 |
155.5 |
|
2022/11/29 |
4 |
159.5 |
|
2022/11/30 |
4 |
163.5 |
|
2022/12/1 |
3 |
166.5 |
|
2022/12/2 |
5 |
171.5 |
|
2022/12/3 |
3 |
174.5 |
|
2022/12/4 |
4 |
178.5 |
|
2022/12/5 |
3 |
181.5 |
|
2022/12/6 |
4 |
185.5 |
|
2022/12/7 |
4 |
189.5 |
|
2022/12/8 |
3 |
192.5 |
|
2022/12/9 |
4 |
196.5 |
|
2022/12/10 |
3 |
199.5 |
|
2022/12/11 |
4 |
203.5 |
3.3 感觉个人的哪些方法还存在不足?哪些方面需要改进?等
对一些基础的知识不清晰,比如对数据的录入跟表达。对编程的时间还是每天时常不稳定。
4. 你知道csdn么,结合使用情况表述他的优点与不足
4.1 csdn给你的直观感受是什么?
可以在其中直接的寻找出所需答案跟解析,对于一些小问题还是可以轻松解决的
4.2 csdn你感觉最不舒服的地方是什么?
有一些要开会员
4.3 你还利用了哪些平台学习编程知识,他们是哪些网站或资源,优点是什么?
百度
5. 你认为影响你学习编程的主要阻力是什么?如何克服!
一些自己的定力
6. 其它(针对课程的学习,请发挥)