1、类与对象
经过前面的学习,Java语言的语法规则和和基本使用已经掌握。接下来学习一些关于Java的高级技术。
1.1、类
1.1.1、介绍类
Java这门编程语言中,首当其冲一个概念就是类,到底什么是类呢,从第一天接触Java开始,一直在写,但却没真正研究过。
类:它是一种抽象的概念。对于初学者来学不容易理解。它代表的是某一特殊的群体、或者是具备一定行为(功能)和属性事物。
为了更好的理解到底什么是类,就从大家生活中的事物入手分析,并让大家慢慢形成概念,进而达到对类比较深刻的理解。
在生活中经常会说到“车”、“人”、 “动物”等这样的词语。请大家想想,在说出这些词语的时候当时脑海里面想的是什么呢?
这里就以“车”为例进行简单的分析:当说出“车”这个词的时候,也许很多人的脑海里面都会想当自己所熟悉的某个品牌,某个系列的车。而在和别人阐述的时候只是采用“车”这个词(字)将其描述而已。也就是说每个人说出的“车”都不一定相同,但都采用相同的字或词将其描述出来。
那么“车”这个词(字)就是对生活中车这类事物一个概述,或者说抽象的总结。可以将“车”这个词看成是对车这类事物的一个统称。而实际生活中的每一辆车都是这个统称下的一个具体的实物。
如果使用Java语言来代表我们人类的语言描述车这一特殊的事物和具体每一辆车这个实物,Java语言采用类class描述某一特殊事物,采用对象表示这一事物的具体每一个个体(实物)。
1.1.2、如何定义类
在Java中采用class关键字定义类。定义类的格式:
修饰符 class 类名{
类中的内容
}
修饰符:public、default、private,如果省略不写,那就是默认的修饰符(default)。
类名:必须符合标识符的定义语法要求,同时还要满足如果是多个单词每个单词首字母大写。
类中的内容:主要根据类的描述信息进行具体的书写。后面详细讲解。
/*
* 演示定义类
*/
public class Car {
}
上面的代码仅仅是定义了类,但是类中并没有任何的其他内容。
1.1.3、类中的成员定义
通过上面的学习基本了解如何定义类,那么如何将使用汉字描述的生活的事物使用Java语言的类完整的定义出来呢?
依然是以“车”为例,进行学习:
先使用文字对车进行描述:
车:
品牌
颜色
价格
行驶的功能
仔细研究上面的文字,会发现车的品牌、颜色、价格等信息是车的一些基本特征(属性)数据。而车的行驶是车的一种功能。那么如果使用Java语言描述,可以将分析后得出的事物的特征(属性)数据采用Java中的变量进行表示,事物的功能采用Java中的方法进行表示。
继续分析上面的文字描述,可以看出不管车具备不具备行驶功能,而它的特征(属性)数据都会独立的存在。也就是说车的功能和特征是相对独立的部分,都属于车这个事物本身应该具备的。因此特征(属性)数据需要采用Java中的成员变量进行描述。
public class Car {
// 车的品牌
String brand;
// 车的价格
int price;
// 车的颜色
String color;
// 车有行驶的功能
public void run(){
System.out.println("一辆"+color+"颜色的"+brand+"车正在行驶");
}
}
课堂练习:描述人
描述人:
人:
年龄
性别
身高
体重
说话
学习
睡觉
分析上面描述的车和人的特征时候,发现有些就是一些普通的数据,但是有些发现不能使用简单的值进行描述。我们将能够使用简单的数据表示的事物的特征称为当前这个事物的属性(基本信息),而将无法使用基本的数据表示的那些特征称为事物的动作(行为、功能)。
因此可以将现实生活中的某一类群体(事物)使用java中的类进行表示:
基本的信息(属性):采用java中的变量表示。
事物的动作(行为、功能):采用Java中的方法表示。
/**
* 使用JAVA中的类,描述生活中的人这个群体
* 人:
年龄
性别
身高
体重
说话
学习
睡觉
*/
public class Person {
// 将事物本身的一些属性信息,采用变量直接写在和方法并列的位置上
int age;
// 性别要根据实际开发中的要求,但是大部分都采用了String
String sex;
// 身高
int height;
// 体重
double weight;
// 在类里面是可以直接书写方法
// 描述说话
public void speak(){
System.out.println("表示人在说话");
}
// 描述学习
public void study(){
System.out.println("正在学习");
}
// 描述睡觉
public void sleep(){
System.out.println("美美滴睡一觉");
}
}
/*
* 演示 如何使用自己定义的类,以及调用其中的属性和行为
*/
public class PersonTest {
/*
* 以后并不是所有的类中都需要main方法,
* 有些类仅仅是在描述事物,这时其中就不需要书写main方法
* 而真正需要独立运行的那些类中才需要main方法,
* 在拥有main方法的这些类中可以去调用那些没有main方法类中的内容
*/
public static void main(String[] args) {
/*
* 在Java中要使用某个类,必须通过new关键字创建出来,才能使用
* 创建某个类对象的格式:
* 类名 引用变量名 = new 类名();
*/
Person p = new Person();
/*
* 要使用自己定义的类中的内容(行为和属性),就只能通过引用变量名去操作
*/
// 给当前这个Person的年龄赋值
p.age = 23;
// 给当前这个Person的性别赋值
p.sex = "不详";
// 调用Person中的行为
p.speak();
}
}
1.2、对象
1.2.1、什么是对象
现在可以使用Java中的类将文字描述的事物转成Java语言。那么重点问题是如何在Java中使用自己定义好的类呢?其实使用Java中的类,和生活中使用具体某个事物的个体(实体)十分类似:
假设现在需要一辆车,那么就需要生产(购买),这样你才能拥有一辆真正的车。而这辆车就是生活真实存在的一个实物(活物、个体、实体),也可以称为生活存在的一个对象。而在Java语言中将“对象”可以理解成真正存在一个实物。然后通过代码去使用这个实物。这个实物就称为Java中的对象。
1.2.2、如何创建对象
在实际生活中使用某个个体可以直接去购买、或者生产、或者用已经存在的。但是在Java的世界里面,任何的个体(对象、实体)都必须使用new关键字来创建出来。
创建对象的方式:
new 类名();
1.2.3、对象的使用
Java中通过new关键字创建出来对象之后,可以在程序中直接使用的。
/*
* 测试Java中的对象
*/
public class TestCar {
/*
* 由于这个程序需要独立运行,因此是需要main方法的
*/
public static void main(String[] args) {
// 创建对象
Car c = new Car();
// 给当前这辆车的品牌赋值
c.brand = "BMW";
// 给当前这辆车的价格赋值
c.price = 4590123;
// 给当前这辆车的颜色赋值
c.color = "白色";
// 调用车行驶的功能
c.run();
}
}
1.3、类和对象的关系
类:可以理解成对生活中的某个群体的一种描述,主要描述的这个群体的共性的特征(属性和行为)。
对象:Java中的对象,其实就是通过已经存在的class,采用new关键字创建出来的那个东西。
1.4、成员变量和局部变量
局部位置:局部是指某个范围。例如:方法的大括号中的这些个范围,它就是一个局部范围。局部变量只在范围内可以使用。
成员位置:在定义好类之后,在类的大括号内部的范围。
局部变量:在局部范围中定义的变量,它们全部属于局部变量,并且它的使用范围就在从定义的位置往下到范围结束。
成员变量:直接在类的成员位置上定义的变量。这些变量不受位置的限制,可以在任何方法中被使用。但是建议将所有的变量定义在类的最前面位置。
成员变量定义之后可以不赋值,它会有默认的值。
局部变量定义之后,在使用之前必须赋值。否则编译报错。
/*
* 成员变量和局部变量
*/
public class Person {
// 成员变量
int c = 456;
public void demo() {
System.out.println(c);
}
public void func() {
// 局部变量
int a = 123;
}
}
1.5、引用变量
在前面介绍数据类型的时候:
基本类型:8种(byte、short、int、long、float、double、char、boolean)。
引用类型(复杂类型):使用类、接口、数组类型定义的一些变量,统一都属于引用(复杂)类型。
引用变量格式: 类、接口、数组类型 变量名 = new 数据类型() 或者 直接赋值其他的引用;
Person p = new Person();
这里的p就是一个Person类型的引用。我们通过p变量就可以间接的去操作Person对象。
如果程序中定义很多个引用变量,在操作的时候,一定要搞清楚每个引用变量各自所代表的不同的对象是谁,然后在调用的过程中搞清楚它们其中各自变量的异同。
只要是类中的成员变量,在随着new创建某个类的对象的时候,这些成员变量全部都会在堆中对象所在的内存中开辟各自的空间。
1.6、值传递和引用传递
public class Person {
int age;
public void speak() {
System.out.println("我的年龄是:" + age);
}
}
public class TestPerson2 {
public static void main(String[] args) {
// 创建Person对象
Person p = new Person();
p.speak();
// 传递的是一个引用变量,会将引用变量中的内存地址传递show方法
show(p);
p.speak();
// 传递的是一个具体的数值,将具体的值传递给show2方法
show2(p.age);
p.speak();
}
// 值传递
public static void show2(int age) { // 使用一个普通的变量接收具体的数据
age = 20;
}
// 引用传递
public static void show(Person p) { // 使用引用变量接收传递的地址
p.age = 40;
}
}
传递值:将某个空间中的具体的数据传递给另外一个空间,修改另外一个空间中的数据,对原始空间不会造成任何的影响。
传递引用:将一个内存地址传递给其他的引用变量,那么就会导致多个引用变量指向同一个内存区域,这样其中任何的引用都可以去操作这块共享的内存区域,那么将导致一旦修改,其他的引用再去操作一定是被改变的后数据。
1.7、匿名对象
匿名对象:就是使用new关键字创建出来的对象,不赋值给任何的引用变量,这个对象称为匿名对象。
/**
* @author wx
* <a href="http://www.kuaixueit.com">快学大数据</a>
*/
public class TestPerson3 {
public static void main(String[] args) {
// 创建Person对象
// Person p = new Person();
// p.speark();
// p.age = 23;
// p.speark();
// 匿名对象
new Person().speak();
new Person().age = 44;
new Person().speak();
/*
* 上面创建了3个Person对象,
* 它们各自都有自己的堆内存空间,
* 因此它们分别拥有自己的成员变量。
* 各自是不会被影响的。
*/
}
}
匿名对象应用:
如果在程序中,某个对象仅仅只使用一次,这时可以采用匿名对象方式来创建这个对象。一个对象如果要被使用多次(最少2次),这时一定要使用引用变量作为对象的名称。通过引用变量操作当前这个对象。
匿名对象产生的问题:
由于匿名对象是没有名称的,因此当匿名对象所在的代码执行完成,这个对象立刻变成垃圾(一个对象如果没有任何引用指向它,这个对象就是垃圾)。等待垃圾回收器收走。
new Person().speark(); 相当于 Person p = new Person(); p.speark(); p = null;
2、API
2.1、什么是api
API:Application Programming Interface 应用程序接口。我们这里介绍API,指的是关于JavaSE的JDK帮助文档。
这里我们可以将API文档理解成我们中文的中的新华字典。
API文档它是帮助我们查阅、理解JDK底层的已经存在的类、接口、抽象类等的使用方式、规则、定义格式等等信息的。
2.2、查阅API
2.3、阅读类
方法摘要:
当前类中所有非私有的方法都会列出来,然后可以根据方法摘要中的信息,去查阅每个方法的定义和使用。
阅读方法摘要的时候:
- 查看方法的返回值类型。
- 查看方法名。
- 查看方法到底要不要接受参数。
接下来一起学习安装的JDK中已经存在一些常用的类,当把这些类的基本使用学习清楚之后,我们需要研究Java中关于类的更加高级一些的技术。
3、String类
3.1、String类介绍
String:它表示的是Java的被双引号引用起来的数据(字符串)。字符串也算一类事物(平时生活中说的每一句话,使用的一些词语等等都可以理解字符串格式的数据),在Java中使用String 类进行描述和封装。如果我们要想操作字符串,就应该找String类。
在Java中任何的的“” 引用起来的数据,都可以看成String 的一个对象。
String s = new String(“abc”);
String s2 = “abc”;
3.2、使用String类
3.2.1、创建String的对象
String类的对象创建方式:
/*
* 演示创建String对象
*/
public class StringDemo {
public static void main(String[] args) {
// 使用双引号引用起来,就是String的一个对象
String s = "学Java";
/*
* 使用new关键字创建String对象
* new String() 这样创建出来的字符串中其实是没有任何的字符内容的,
* 就是一个空串,类似于""
*/
String s2 = new String();
String s3 = "";
/*
* 创建String对象的同时,指定当前String对象所对应的字符串数据
*/
String s4 = new String("学JavaEE");
// 上面的代码类似于
String s5 = "学JavaEE";
}
}
3.2.2、String的方法使用
// 需求:获取字符串指定位置上的字符数据。
String s = "学Java";
// 获取第三个字符
char ch = s.charAt(2);
System.out.println(ch);
// 需求:获取字符串中共计有多少个字符
int len = s.length();
System.out.println(len);
// 需求:判断字母'a'字符出现的次数
String s = "学Java";
// 定义变量,作为计数器
int count = 0;
// 使用循环提供字符串中每个字符的下标
for( int i = 0 ; i < s.length() ; i++ ) {
// 取出字符串中的每个字符
char c = s.charAt(i);
// 判断字符是否是要统计的那个字符
if( 'a' == c ) {
count++;
}
}
// 循环结束,打印次数
System.out.println("字母'a'出现的次数是:"+count);
// 需求:将字符串中的所有字符全部转成大写
String s2 = "学Java";
String s3 = s2.toUpperCase();
System.out.println(s3);
// 需求:将字符串中的所有字符全部转成小写
String s4 = "学JAVA";
String s5 = s4.toLowerCase();
System.out.println(s5);
// 需求:从字符串中截取出Java
String s = "学Java";
String s2 = s.substring(1);
System.out.println(s2);
// 需求:截取西安
String s3 = "陕西省西安市长安区";
String s4 = s3.substring(3, 6);
System.out.println(s4);
// 需求:判断两个字符串是否相同
String s = "学Java";
String s2 = "学JAVA";
// equals : 区分大小写比较
boolean b = s.equals(s2);
// equals :不 区分大小写比较
boolean b2 = s.equalsIgnoreCase(s2);
System.out.println(b);
System.out.println(b2);
自主练习:从身份证号码中截取出出生的年月日数据。
3.2.3、String中的判断方法
/*
* 判断两个字符串是否相同
* 以后只要是Java中的复杂类型数据,判断是否相同,
* 都需要调用对应类中的方法的。不能直接使用==进行比较。
*/
public static void demo() {
String s = "学Java";
String s2 = "学java";
/*
* 严格区分大小写的判断
*/
boolean b = s.equals(s2);
System.out.println("区分大小写:"+b);
/*
* 不区分大小写的比较
*/
boolean c = s.equalsIgnoreCase(s2);
System.out.println("不区分大小写:"+c);
}
/*
* 判断一个短的字符串是否在一个长的字符串中存在
*/
public static void demo2() {
String s = "good good study , day day up";
/*
* contains :判断是否包含指定的字符串数据
*/
boolean b = s.contains("study");
System.out.println("判断是否包含指定的字符串:"+b);
}
/*
* 判断String对象是否表示的是一个空串
*/
public static void demo3() {
String s = " ab";
boolean b = s.isEmpty();
System.out.println("判断空串:"+b);
}
/*
* 判断字符串以指定的内容开始或结束
*/
public static void demo4() {
String s = "xueJava技术.docx";
/*
* 判断是否以"xue"开始
*/
boolean b = s.startsWith("xue");
System.out.println("判断字符串是否以\"xue\"开始:"+b);
/*
* 判断以.docx结尾
*/
boolean c = s.endsWith(".docx");
System.out.println("判断字符串是否以\".docx\"结尾:"+c);
}
3.2.4、String的获取方法
/*
* 获取长度
*/
public static void demo() {
String s = "abcde";
int len = s.length();
System.out.println("字符串的长度是:"+len);
}
/*
* 获取指定字符在字符串中的位置:
* 其实字符串底层就是一个char数组,每个字符都有自己的下标
*/
public static void demo2() {
String s = "xuexijava";
/*
* 获取 字符 'x' 的位置
* indexOf : 从前往后找第一次出现的位置
*/
int index = s.indexOf('x');
System.out.println("'x'在字符串中的位置:"+index);
/*
* indexOf('x' , 1) :从指定位置开始往后找第一次出现的位置
* 如果指定的内容在 字符串中没有,返回-1
*/
int index2 = s.indexOf('x' , 1);
System.out.println("'x'在字符串中的位置:"+index2);
/*
* 从后往前找第一次出现的位置:
*/
int lastIndex = s.lastIndexOf("java" , 4);
System.out.println("从后往前找第一次出现的位置:"+lastIndex);
}
// 根据指定的位置获取位置上的字符数据
public static void demo3() {
String s ="xuexijava";
/*
* 找出3位置上的字符内容
*/
char ch = s.charAt(3);
System.out.println("字符串3下标位置上的字符数据是:"+ch);
}
/*
* 需求:统计指定的某个字符在指定的另外一个字符串中出现的次数
*/
public static void demo4() {
String s = "qwe";
// 统计'a'的次数
int count = 0;
// 使用for循环提供字符串的下标。取出每个字符和指定的'a'比较
for( int i = 0 ; i < s.length() ; i++){
// 取出这个字符数据
char ch = s.charAt( i );
// 判断
if( ch == 'a' ){
count++;
}
}
System.out.println("'a'出现的次数是:"+count);
}
练习:统计一个字符串中大写字母、小写字母、数字字符、其他字符它们各自的次数。
/*
* 截取字符串
*/
public static void demo5() {
String s = "xuexijava";
/*
* 截取出java
* substring(5)从指定的位置截取到结束位置
*/
String str = s.substring(5);
System.out.println("截取到的字符串是:"+str);
/*
* 截取出xuexi
* substring(0, 5) 从指定的位置开始截取到指定的位置,但是结束位置不包含在其中。
*/
String str2 = s.substring(0, 5);
System.out.println("演示指定起始位置和结束位置截取字符串:"+str2);
}
// 从身份证号码中截取出出生年月日
static void demo6() {
String idCard = "610110199910101234";
String year = idCard.substring(6, 10);
String month = idCard.substring(10, 12);
String day = idCard.substring(12, 14);
System.out.println(year+"年"+month+"月"+day+"日");
}
3.2.5、String的转换方法
//大小写转换
public static void demo() {
String s = "XueJava";
//全部转大写
String s2 = s.toUpperCase();
// 全部转小写
String s3 = s.toLowerCase();
System.out.println(s);
System.out.println(s2);
System.out.println(s3);
}
// 连接2个字符串
public static void demo2() {
String s = "xue";
String s2 = "java";
// 将两个字符串连接到一起
String s3 = s.concat(s2);
System.out.println(s3);
// 如果仅仅是连接两个字符串,可以直接使用+
String s4 = s + s2;
System.out.println(s4);
}
// 将字符串转字符数组
public static void demo4() {
String s = "abc";
/*
* 转成字符数组
*/
char[] cs = s.toCharArray();
for (int i = 0; i < cs.length; i++) {
System.out.println("cs[i] = " + cs[i] );
}
}
// 将字符串转字节数据
public static void demo3() {
String s = "abc";
// getBytes : 将字符串转字节数组
byte[] bs = s.getBytes();
// 遍历打印数组
for (int i = 0; i < bs.length; i++) {
System.out.println("bs[i] = " + bs[i]);
}
}
3.3、总结String
String类是由JDK中提供的一个专门用于对字符串进行操作的类,因此在程序中遇到与字符串相关的操作的时候,需要在第一时间想到使用String类,而不是想着自己如何写代码去实现具体的功能。这种编程思想正是JAVA这门语言所提倡的方式。
String类中还有其他更多的方法,在后续的学习过程中会继续介绍。