Java基础入门教程
学习配套软件:eclipse
1、基础知识
(1)常用DOS命令:切换盘–>E:,cd–>进入文件,可多级,cd … -->回退一级,cd \ -->回退到根盘,cls–>清屏,exit–>退出命令提示符
(2)关键字:被java语言赋予了特定含义的单词(50个左右)
特点:关键字的字母全部小写
(3)常量:在程序运行过程中,其值不可以发生改变!
字符串常量->双引号,字符常量->单引号,空常量不能直接输出!
(4)数据类型
1、计算机存储单元:计算机存储设备的最小信息单元:位(bit),计算机中和最小的存储单元:字节(byte),1B=8 bit,1KB=1024B
2、Java语言是强类型语言,对于每种数据都给出了明确的数据类型,不同的数据类型也分配了不同的内存空间,所以它们表示的数据大小也是不一样的。
3、数据类型内存占用和取值范围:
(5)变量:在程序运行过程中,其值可以发生改变!
1、变量定义:数据类型 变量名=变量值(例:int a=10;)
2、变量使用:取值(取变量名即可–>a)和修改值(变量名=修改值; -->a=20;)
3、注意事项:变量名不能重复;变量未赋值不能使用;long类型定义时后加L(防止整数过大);float后加F(防止类型不兼容)
(6)标识符:就是给类,方法,变量等起名字的符号
1、定义规则:由数字、字母、下划线和美元符($)组成;不能以数字开头;不能是关键字;区分大小写
2、命名约定:
(方法、变量)小驼峰命令法:一个单词–>首字母小写,如name;多个单词–>第一个首字母小写,其他大写,比如firstName
(类)大驼峰命令法:一个单词–>首字母大写,如Student;多个单词–>每个单词首字母都大写,比如GoodStudent
(7)类型转换
分类:
1、自动类型转换:把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。double d=10;输出10.0(小赋给大)
2、强制类型转换:把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。int a=(int)88.88;输出88(大赋给小)
2、运算符+控制结构
(1)算术运算符(+,-,*,/,%)
1、运算符:对常量或者变量进行操作的符号。算术运算符:+
表达式:用运算符把常量或者变量连接起来的符合java语法的句子就可以称为表达式,不同运算符连接的表达式体现的是不同类型的表达式。算数表达式:a+b
2、字符“+”操作:ASCII码(‘A’–>65,‘a’–>97,‘0’–>48,A-Z,a-z,0-9字符的ASCII码是连续的)
算术表达式中包含多个基本数据类型的值的时候,整个算术表达式的类型会自动提升!
规则:byte,short,char–>int,整个表达式的类型自动提升到表达式中最高等级操作数同样的类型。
等级顺序:byte,short,char–>int–>long–>float–>double
3、字符串“+”操作:拼接:字符串+字符串,字符串+int,int+字符串,字符串+int+int。
int+int+字符串(这个先int相加再拼接),执行顺序:从左往右!
(2)赋值运算符:=,+=,-=,*=,/=,%=(后5个隐含强制类型转换)
(3)自增自减运算符:++,–(每次变化—>1,前后位置影响执行顺序)
(4)关系运算符:==,!=,>,>=,<,<=,结果为boolean类型(true,false)
(5)逻辑运算符:用来连接关系表达式的运算符,也可直接连接bool类型的常量或者变量
1、基本逻辑运算符:逻辑与:&,逻辑或:|,逻辑异或:^(不同为true,同为false),逻辑非:!
2、短路逻辑运算符:短路与:&&,短路或:||,能判断则直接返回结果,不再执行后面的表达式。
(6)三元运算符:a>b?a:b,若表达式a>b为true则返回a,否则返回b
(7)数据输入:Scanner使用的基本步骤
1、导入Scanner:import java.util.Scanner;
2、创建对象:Scanner sc=new Scanner(System.in);
3、接收数据:int i=sc.nextInt();(仅有变量名可以变,变了要对应)
(8)流程控制:顺序结构,分支结构,循环语句
1、顺序结构:按程序中代码的先后顺序,依次执行。
2、分支结构:if语句,switch语句
一、if语句格式:if(关系表达式){语句体;} if(关系表达式){语句体1;} else{语句体2;}
if(关系表达式1){语句体1;} else if(关系表达式2){语句体2;}…else{语句体n+1;}
数据测试:正确数据,边界数据,错误数据
二、switch语句:break–>结束switch语句!不写break则case穿透,直至遇到一个break
switch(表达式){
case 值1:语句体1;break;
case 值2:语句体2;break;
…
default:语句体n+1;break;
}
3、循环结构:for,while,do…while
一、for循环语句:for(int i=0;i<n;i++) {循环体语句;}
3位数的个位数:n%10,十位数:n/10%10,百位数:n/100
求任意数字的指定位上的数值:先使用整除操作将要求的数字移动到个位上,再使用取余操作取出最后一位上的值。
二、while语句:初始化语句; while(条件判断语句) {循环体语句; 条件控制语句;}
三、do…while循环语句:初始化语句; do{循环体语句;条件控制语句;} while(条件判断语句);
四、循环语句的区别:do…while至少执行一次!仅在for里面初始化的变量,for结束后不能使用
死循环:for(;😉{},while(true){},do{}while(true); ctrl+c可以结束死循环,退出程序
五、跳转控制语句
continue;–>用在循环中,基于条件控制,跳过某次循环体内容的执行,继续下一次的执行
break;–>用在循环中,基于条件控制,终止循环内容的执行,也就是说结束当前的整个循环
六、循环嵌套
语句结构:顺序语句,分支语句,循环语句。任何语句对外都可以看成是一句话,一句代码。
七、Random:用于产生一个随机数,使用步骤:
1、导包:import java.util.Random;
2、创建对象:Random r=new Random();
3、获取随机数:int number=r.nextInt(10); 0-9,不包括10
3、数组
(1)一次性声明大量用于存储数据的变量,通常是同类型数据!
1、格式一:int[] arr,格式二:int arr[]
2、初始化:java中的数组必须初始化(为数组中的元素分配内存空间,并为每个元素赋值)才能使用。
2.1、动态初始化:初始化时只指定数组长度,由系统为数组分配初始值,一般为0。格式:数据类型[] 变量名=new 数据类型[数组长度];
例子: int[] arr=new int[10];(会有默认值!)
3、数组元素访问
数组变量访问方式:数组名(地址), 数组元素访问方式:数组名[索引]
索引:数组中数据的编号方式,从0开始,连续的,逐增1.
作用:用于访问数组中的数据使用,数组名[索引]=变量名,是一种特殊的变量名。
4、内存分配
Java程序在运行时,需要在内存中分配空间,为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
栈内存:存储局部变量,定义在方法中变量,使用完毕立即消失。
堆内存:存储new出来的内容(实体,对象),每一个new出来的东西都有一个地址值,使用完毕,会在垃圾回收器空闲时被回收。
5、静态初始化:初始化时指定每个数组元素的值,由系统决定数组长度
格式:数据类型[] 变量名=new 数据类型[]{数据1,数据2,数据3,…};
例子:int[] arr=new int[]{1,2,3};
简化:数据类型[] 变量名={数据1,数据2,数据3,…};
例子:int[] arr={1,2,3};
6、数组操作常见小问题:
索引越界:访问了数组中不存在的索引对应的元素,造成索引越界问题
空指针异常:访问的数组已经不再指向堆内存的数据,造成空指针异常
null:空值,引用数据类型的默认值,表示不指向任何有效对象
7、数组常见操作:遍历、获取数组元素数量(数组名.length),获最大值
4、方法
(1)概述:
What:是将具有独立功能的代码块组织成一个整体,使其具有特殊功能的代码集。
注意:方法必须先创建才可以使用,该过程成为方法定义;方法创建后并不是直接运行的,需要手动使用后执行,该过程称为方法调用。
(2)定义和调用(不带参数)
定义格式:public static void 方法名() {
//方法体
}
范例:public static void isEventNumber() {
System.out.println(“Hello World!”);
}
方法调用:方法名(); 范例:isEventNumber();
(3)定义和调用(带参数)
格式:public static void 方法名(数据类型 参数1,数据类型 参数2,…) {… …}
范例:public static void isEventNumber(int number1,int number2,…){… … }
注意:方法定义时,参数中的数据类型和变量名都不能缺少,缺少任意一个程序将报错,多个参数之间使用(,)分隔
调用方法:方法名(参数1,参数2,…); 实参个数+数据类型得对应方法定义中的!
形参:方法定义中的参数,等同于变量定义格式,例 -->int number;
实参:方法调用中的参数,等同于使用变量或常量,例–>10,number
(4)定义和调用(带返回值)
格式:public static 数据类型 方法名(){
return 数据;
}
范例:public static boolean isEventNumber(int number){
return true;
}
注意:方法定义时return后面的返回值与方法定义上的数据类型要匹配,否则程序将报错。
方法调用:方法名(参数); 范例:isEventNumber(5);
boolean flag=isEventNumber(5); 方法的返回值通常要使用变量接收,否则该返回值将无意义。
(5)方法的注意事项
a、方法不能嵌套定义
b、void表示无返回值,可以省略return,也可单独书写return; 但不加数据
定义:Two明确:明确返回值类型,无返回值则void;明确参数的类型和数量
调用:void类型的方法直接调用即可,非void类型方法,推荐使用变量接收调用
(6)方法重载:指同一个类中定义的多个方法之间的关系
条件:多个方法在同一类中+具有相同的方法名+参数类型不同或数量不同
特点:重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式;重载仅针对同一类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否互相构成重载。
在调用的时候,Java虚拟机会通过参数的不同(类型/数量)来区分同名方法。
(7)方法参数传递
一、对于基本数据类型的参数,形式参数的改变,不影响实际参数的值。运行结束后两个方法都要出栈。
二、对于引用类型的参数,形式参数的改变会影响实际参数的值!运行结束后两个方法都要出栈。
(8)Debug:是供程序员使用的调试工具,它可以用于查看代码的执行流程,也可以用于追踪程序执行过程来调试程序。
Debug调试:又断点调试,断点其实是一个标记,告诉我们从哪里开始查看。
流程:如何加断点(行号)、如何运行加断点程序(Debug小甲虫图标)、看哪里(Debug,Variables窗口)、点哪里(f5,逐语句)、如何去断点(右键)
注意事项:如果数据来自于键盘输入,一定要记住输入数据,不然就不能往下查看了。
5、面向对象基础
(1)类与对象
A、对象:万物皆对象,客观存在的事物皆为对象。
B、类:是对现实生活中一类具有共同属性和行为的事物的抽象。
C、类的特点:类是对象的数据类型;类是具有相同属性和行为的一组对象的集合。
D、对象的属性:对象具有的各种特征,每个对象的每个属性都拥有特定的值。
E、对象的行为:对象能够执行的操作。
F、二者关系:类是对现实生活中一类具有共同属性和行为的事物的抽象,对象是能够看得到摸得着的真实存在的实体。
!类的定义(类是Java程序的基本组成单位)
A、类是对现实生活中一类具有共同属性和行为的事物的抽象,确当对象将会拥有的属性和行为。
B、类的组成:属性和行为
属性:在类中通过成员变量来体现(类中方法外的变量–>成员变量)
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可,方法中的变量–>局部变量)
C、定义类的步骤:定义类、编写类的成员变量、编写类的成员方法(无static)
public class 类名{
//成员变量
变量1的数据类型 变量1;
变量2的数据类型 变量2;
…
//成员方法(无static)
方法1;
方法2;
…
}
在另一个测试类中,可在main函数中创建对象,调用定义的类。
(2)对象内存图
(3)成员变量和局部变量
成员变量–>类中方法外的变量
局部变量–>方法中的变量
(4)封装
一、private关键字:是一个权限修饰符,可以修饰成员(成员变量和成员方法),作用是保护成员不被别的类使用,被private修饰的成员只能在本类中才能访问。
针对private修饰的成员变量,如果需要被其它类使用,提供相应的操作:
get变量名(); -->用于获取成员变量的值,方法用public修饰(变量名首字母大写)
set变量名(); -->用于设置成员变量的值,方法用public修饰(变量名首字母大写)
二、this关键字
A、this修饰的变量用于指代成员变量(方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,带this修饰的就是成员变量)
B、方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量。
C、什么时候下使用?–> 解决局部变量隐藏成员变量,就是形参和成员变量同名时使用this关键字
D、this代表所在类的对象引用,方法被哪个对象调用,this就代表哪个对象
三、面向对象三大特征:封装、继承、多态
概述:封装是面向对象编程语言对客观世界的模拟,客观世界成员变量都是隐藏在对象内部的,外界是无法直接操作的。
封装原则:将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
如:成员变量private,提供对应的getXxx()/setXxx方法
封装好处:通过方法来控制成员变量的操作,提高了代码的安全性;把代码用方法进行封装,提高了代码的复用性。
(5)构造方法
(一种特殊的方法,用于创建对象)
功能:主要是完成对象数据的初始化。
格式:public class 类名{
//构造方法
修饰符(public) 类名(参数){
}
}
注意事项:
如果没有定义构造方法,系统将给出一个默认的无参数构造方法,如果定义了构造方法,系统将不再提供默认的构造方法。
如果定义了带参数的构造方法,还要使用无参数的构造方法,就必须再写一个无参数构造方法。
无论是否使用,都建议手动书写无参数构造方法。
标准类的制作规则
one、成员变量:使用private修饰
two、提供一个无参构造方法、提供一个带多个参数的构造方法
three、提供每一个成员变量对应的setXxx()、getXxx(),显示对象信息show()
four、测试类:创建对象并为成员变量赋值的两种方式:无参构造方法创建对象后使用setXxx(),带参构造函数直接创建带有属性值的对象,new时赋值。
//(代码示例具体运行时记得package 对应的包)
//学生类
public class Student {
//成员变量:使用private修饰
private String name;
private int age;
//构造方法(重载),无参和带参(可带一个或多个)
public Student() {
}
public Student(String name,int age) {
this.name=name;
this.age=age;
}
public Student(String name){
this.name=name;
}
public Student(int age){
this.age=age;
}
//显示对象信息
public void show() {
System.out.println(name+","+age);
}
//private成员变量,提供setXxx(),getXxx()方法
//this.修饰的是成员变量,没有修饰的就是局部变量
public void setAge(int age) {
if(age<0||age>120) {
System.out.println("你给的年龄有误!");
}else {
this.age=age;
}
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name=name;
}
public String getName(){
return name;
}
}
//学生测试类
public class StudentDemo {
public static void main(String[] args) {
//创建对象,使用无参构造方法
Student s1=new Student();
s1.setName("肖小恩");
s1.setAge(22);
//两种输出方法
s1.show();
System.out.println(s1.getName()+","+s1.getAge());
//创建对象,使用带参构造方法
Student s2=new Student("杨诗婷",22);
//两种输出方法
s2.show();
System.out.println(s2.getName()+","+s2.getAge());
}
}
6、字符串
(1)API
Application Programming Interface 应用程序编程接口
Java API:指的就是JDK中提供的各种功能的Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可,我们可以通过帮助文档来学习这些API如何使用。
(2)String
String
类在java.lang包下,使用时不需要导包
String
类代表字符串。 Java程序中的所有字符串文字(例如"abc"
)都被实现为此类的实例。双引号字符串,都是String类的对象。
特点:
- 字符串不变; 它们的值在创建后不能被更改
- 虽然String对象是不可变的,它们可以被共享
- 字符串效果上相当于字符数组(char[]),但是底层原理是字节数组(byte[])
String 构造方法
:(根据byte数组内容创建的字符串对象,根据ASCII转)
String对象的特点
:
一、通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同。
二、以“”方式给出的字符串对象,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串池中维护。
字符串比较
:使用==作比较(地址值)
基本类型:比较的是数据值是否相同
引用类型:比较的是地址值是否相同
字符串是对象,它比较内容是否相同是通过一个方法来实现的,这个方法叫:equals(),public boolean equals(Object anObject):将此字符串与指定对象进行比较。由于我们比较的是字符串对象,所以参数直接传递一个字符串。
遍历字符串
:public char charAt(int index):返回指定索引处的char值,字符串的索引也是从0开始的。
使用方法:字符传对象.charAt(index)–>返回字符串对象在该索引位置的字符
字符串长度
:字符串对象.length(); 数组长度:数组名.length;
(代码示例具体运行时记得package 对应的包)
//1、用户登录,将用户输入的用户名+密码与已知的比较,内容相同则登陆成功
import java.util.Scanner;
public class Login_in {
public static void main(String[] args) {
//定义两个String类型变量存储已知的用户名和密码
String username="xiao en";
String passport="123456";
//创建对象
Scanner sc=new Scanner(System.in);
for(int i=0;i<3;i++)
{
//用户输入用户名和密码
System.out.println("请输入用户名和密码:");
String a=sc.nextLine();
String b=sc.nextLine();
//str1.equals(str2)比较两个String的内容是否相同
if(a.equals(username) && b.equals(passport))
{
System.out.println("欢迎登录本站!");
break;
}else {
if(i<2) {
System.out.println("账号或密码输入有误,请重试!还有"+(2-i)+"次机会!\n");
}else {
System.out.println("对不起,你输入次数已达三次,请稍后再试!");
}
}
}
}
}
//2、遍历字符串,用户输入一个字符串,控制台遍历输出
import java.util.Scanner;
public class see_all {
public static void main(String[] args) {
//创建对象
Scanner sc=new Scanner(System.in);
System.out.print("请输入一个字符串:");
String str=sc.nextLine();
//str.length();-->获取该字符串长度
//str.charAt(index);将返回该索引位置的字符
for(int i=0;i<str.length();i++){
System.out.println(str.charAt(i));
}
}
}
//3、用户输入一个字符串,统计其中大写、小写字母以及数字的个数,其他忽略
import java.util.Scanner;
public class count {
public static void main(String[] args) {
//创建对象
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str=sc.nextLine();
int big=0,small=0,number=0;
for(int i=0;i<str.length();i++) {
if('A'<=str.charAt(i) && str.charAt(i)<='Z') {
big++;
}else if('a'<=str.charAt(i) && str.charAt(i)<='z') {
small++;
}else if('0'<=str.charAt(i) && str.charAt(i)<='9') {
number++;
}else {
} //其他字符直接跳过
}
System.out.println("大写字母个数:"+big+",小写字母个数:"+small+",数字个数:"+number);
}
}
//4、拼接字符串,int数组{1,2,3}元素拼接成一个字符串返回,调用方法输出拼接后的字符串[1,2,3]
public class pluschar {
public static void main(String[] args) {
int[] a= {
1,2,3};
System.out.println("拼接输出结果:"+plus(a));
}
//拼接方法
public static String plus(int[] a) {
String str="[";
for(int i=0;i<a.length-1;i++) {
str=str+a[i]+",";
}
str=str+a[a.length-1]+"]";
return str;
}
}
//5、键盘输入一个字符串,调用方法时实现字符串反转,并输出结果
import java.util.Scanner;
public class turnchar {
public static void main(String[] args) {
//创建对象
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str=sc.nextLine();
System.out.println("反转后的字符串:"+turn(str));
}
//字符串反转方法
public static String turn(String str) {
String s="";
for(int j=str.length()-1;j>=0;j--) {
s=s+str.charAt(j);
}
return s;
}
}
方法名 | 说明 |
---|---|
public boolean equals(Object anObject) | 比较字符串的内容,严格区分大小写(用户名和密码)(str.equals(str2)) |
public char charAt(int index) | 返回指定索引的 char 值( str.charAt(index) ) |
public int length() | 返回字符串的长度( str.length() ) |
public boolean endsWith(String suddix) | 测试字符串是否以指定的后缀结尾 |
(3)StringBuilder:内容可变的字符串类,可以看成是容器
问题:对字符串进行拼接操作,每次拼接都会构建一个新的String对象,即耗时又耗空间,但可以通过Java提供的StringBuilder类来解决这个问题。
构造方法:
方法名 | 说明 |
---|---|
public StringBuilder() | 创建一个空白可变字符串都西昂,不含有任何内容 |
public StringBuilder(String str) | 根据字符串的内容,创建可变字符串对象。StringBuilder str=new StringBuilder(str1); |
public StringBuilder append(任意类型) | 添加数据,并返回对象本身(str.append(数据);) |
public StringBuilder reverse() | 返回相反的字符序列(str.reverse();) |
StringBuilder和String相互转换
public String toString():实现把StringBuilder转换为String
public StringBuilder(String str):实现String转换为StringBuilder
public class StringBuilder_String {
public static void main(String[] args) {
//StringBuilder转换为String --> strB.toString();
StringBuilder sb=new StringBuilder();
sb.append("hello");
String s=sb.toString();
System.out.println("s:"+s);
//String转化为StringBuilder -->new StringBuilder(str)
String str="你好啊";
StringBuilder sbb=new StringBuilder(str);
System.out.println("sbb:"+sbb);
}
}
/*升级需求:
1、拼接字符串,int数组中的数据按照指定的格式拼接成一个字符串返回
调用该方法,要求方法内用StrigBuilder进行拼接,返回String,并在控制台输出结果。
int[] arr={1,2,3};执行方法后输出[1,2,3]
2、字符串翻转:键盘输入字符串,调用方法(StringBuilder)翻转返回String,在控制台输出结果,
*/
import java.util.Scanner;
public class example {
public static void main(String[] args) {
//拼接字符串
int[] arr= {
1,2,3};
System.out.println(plus(arr));
//翻转字符串
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str=sc.nextLine();
System.out.println("反转结果:"+turn(str));
}
//拼接字符串方法
public static String plus(int[] arr) {
StringBuilder str=new StringBuilder();
str.append("[");
for(int i=0;i<arr.length-1;i++) {
str.append(arr[i]).append(",");
}
str.append(arr[arr.length-1]).append("]");
String st=str.toString();
return st;
}
//反转字符串方法
public static String turn(String str) {
StringBuilder st=new StringBuilder();
for(int i=str.length()-1;i>=0;i--) {
st.append(str.charAt(i));
}
String result=st.toString();
return result;
//方法内代码可用一行代替:return new StringBuilder(str).reverse().toString();
}
}
7、集合基础
编程的时候如果要存储多个数据,使用固定长度的数组存储格式,不一定满足我们的需求,更适应不了变化的需求,我们可以选择集合。
集合:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变。(如ArrayList)
(1)ArrayList:可调整大小的数组实现,是一种特殊的数据类型,泛型
构造方法和添加方法
:
方法名 | 说明 |
---|---|
public ArrayList() | 创建一个空的集合对象 |
public boolean add(E e) | 将指定元素追加到此集合的末尾 |
public void add(int intdex,E element) | 再在此集合的指定位置插入指定的元素 |
集合常用方法
方法名 | 说明 |
---|---|
public boolean remove(Object o) | 删除指定的元素,返回删除是否成功 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
//存储学生对象并遍历(要求数据键盘输入数据)
import java.util.ArrayList;
import java.util.Scanner;
public class array_Student {
public static void main(String[] args) {
//创建集合对象
ArrayList<Student> arr=new ArrayList<Student>();
for(int k=0;k<3;k++) {
addStudent(arr);
}
//遍历输出
for(int i=0;i<arr.size();i++) {
Student ss=arr.get(i);
System.out.println("Name:"+ss.getName()+"Age:"+ss.getAge());
}
}
public static void addStudent(ArrayList<Student> arr) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入学生姓名:");
String name=sc.nextLine();
System.out.println("请输入学生年龄:");
String age=sc.nextLine();
Student s=new Student();
s.setName(name);
s.setAge(age);
//将Student对象添加至集合
arr.add(s);
}
}
8、学生管理系统
//学生类
package Java140_149;
public class Student {
//学号、姓名、年龄、居住地
private String sid;
private String name;
private String age;
private String address;
//无参构造函数
public Student(){
}
//alt+shift+s-->select super constructor to invoke-->select all
//即可生成带有所有参数的构造方法
public Student(String sid, String name, String age, String address) {
super();
this.sid = sid;
this.name = name;
this.age = age;
this.address = address;
}
//alt+shift+s-->Generate Getters and Setters-->select all
//即可生成所有参数的set和get函数
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
//学生管理系统(暂无文件操作)
/*
思路:1、定义学生类
2、主界面的代码编写
3、添加学生的代码编写
4、删除学生的代码编写
5、修改学生的代码编写
6、查看学生的代码编写
*/
package Java140_149;
import java.util.ArrayList;
import java.util.Scanner;
public class Student_manage {
public static void main(String[] args) {
//创建集合对象,用于存储学生数据
ArrayList<Student>array=new ArrayList<Student>();
int input;
while(true){
System.out.println("---------欢迎来到学生管理系统---------");
System.out.println("1、添加学生\n2、删除学生\n3、修改学生\n4、查看所有学生\n5、退出系统\n请输入你的选择(1-5):");
Scanner sc=new Scanner(System.in);
input=sc.nextInt();
switch(input)
{
case 1:
//System.out.println("添加学生信息");
addStudent(array);
break;
case 2:
//System.out.println("删除学生信息");
deleteStudent(array);
break;
case 3:
//System.out.println("修改学生信息");
changeStudent(array);
break;
case 4:
//System.out.println("查看所有学生信息");
playStudent(array);
break;
case 5:
System.out.println("谢谢使用!");
//break;
System.exit(0);//JVM退出
default:
System.out.println("输入有误!请重试\n");
}
}
}
//添加学生信息方法
public static void addStudent(ArrayList<Student> array) {
Scanner scan=new Scanner(System.in);
String sid;
while(true) {
System.out.println("请输入学生学号:");
sid=scan.nextLine();
if(!Isuse(array,sid)) {
System.out.println("你输入的学号已经被使用,请重新输入!");
}else {
break;
}
}
System.out.println("请输入学生姓名:");
String name=scan.nextLine();
System.out.println("请输入学生年龄:");
String age=scan.nextLine();
System.out.println("请输入学生居住地:");
String address=scan.nextLine();
Student stu=new Student();
stu.setSid(sid);
stu.setName(name);
stu.setAge(age);
stu.setAddress(address);
//或者一句话--> Student stu=new Student(sid,name,age,address);
array.add(stu);
System.out.println("添加学生信息成功!\n");
}
//判断学号是否已使用,没有相同的,可用返回true
public static boolean Isuse(ArrayList<Student> array,String sid) {
for(int i=0;i<array.size();i++) {
Student s=array.get(i);
if(s.getSid().equals(sid)) {
return false;
}
}
return true;
}
//查看学生方法(打印)
public static void playStudent(ArrayList<Student> array){
if(array.size()==0) {
System.out.println("无学生信息,请添加后再查询噢!\n");
return; //结束本方法
}
System.out.println("学号\t姓名\t年龄\t居住地");
for(int i=0;i<array.size();i++) {
//集合中对象是Student
Student s=array.get(i);
System.out.println(s.getSid()+"\t"+s.getName()+"\t"+s.getAge()+"岁\t"+s.getAddress());
}
}
//删除学生信息方法
public static void deleteStudent(ArrayList<Student> array) {
Scanner scann=new Scanner(System.in);
System.out.println("请输入你要删除的学生学号:");
String sid =scann.nextLine();
int index=-1;
for(int i=0;i<array.size();i++) {
Student sss=array.get(i);
if(sss.getSid().equals(sid)) {
index=i;
break;
}
}
if(index==-1) {
System.out.println("该学生不存在\n");
}else {
array.remove(index);
System.out.println("删除学生信息成功!\n");
}
}
//修改学生信息方法
public static void changeStudent(ArrayList<Student> array) {
Scanner scc=new Scanner(System.in);
System.out.println("请输入你要修改的学生的学号:");
String sid=scc.nextLine();
int index=-1;
for(int i=0;i<array.size();i++) {
Student sss=array.get(i);
if(sss.getSid().equals(sid)) {
index=i;
break;
}
}
if(index==-1) {
System.out.println("该学生不存在!\n");
}
else {
System.out.println("请输入学生新姓名:");
String name=scc.nextLine();
System.out.println("请输入学生新年龄:");
String age=scc.nextLine();
System.out.println("请输入学生新居住地:");
String address=scc.nextLine();
Student s=new Student(sid,name,age,address);
array.set(index,s);//i为索引,后面为新对象
System.out.println("修改学生信息成功!\n");
}
}
}
9、继承
(1)相同特征
:相同的属性(成员变量)、相同的方法(成员方法),用一个类来表示相同特征
继承是面向对象三大特征之一,可以使得子类(亦称派生类)具有父类(亦称基类、超类)的属性和方法,还可以在子类中重新定义,追加属性和方法。
格式:public class 子类名 extends 父类名{}
继承中子类的特点:子类可以有父类的内容,还可以有自己特有的内容
(2)好处与弊端
好处:1、提高了代码的重用性(多个类相同的成员可以放到同一个类中)
2、提高了代码的维护性(如果方法代码需要修改,修改一处即可)
弊端:继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现不得不跟着变化,削弱了子类的独立性。
When使用继承:1、继承体现关系:is a
2、假设法:我有两个类A和B,如果他们满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承。
3、举例:苹果和水果(√),猫和动物(√),猫和狗(×)
(3)继承中变量的访问特点
在子类方法中访问一个变量寻找顺序:子类局部范围找–>子类成员范围找–>父类成员范围找–>如果都没有就报错(不考虑父亲的父亲…)
(4)super
this:代表奔雷对象的引用
super:代表父类存储空间的表示(可以理解为父类对象的引用)
(5)继承中构造方法的访问特点
1、子类中所有构造方法默认都会访问父类中的无参的构造方法,Why?
because:子类会继承父类的数据,可能还会使用父类的数据,所以,子类在初始化之前,一定要先完成父类数据的初始化;每一个子类构造方法的第一条语句默认:super()
2、如果父类中没有无参构造方法,只有带参的,How?
通过使用super关键字显式调用父类中的带参构造方法
在父类中自己提供一个无参构造方法(推荐)
(6)继承中成员方法的访问特点
通过子类对象访问一个方法寻找顺序:子类成员范围找–>父类成员范围找–>如果都没有就报错(不考虑父亲的父亲…)
(7)super内存图
(8)方法重写
概述:子类中出现了和父类一模一样的方法声明
应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容。
@Override:是一个注解,可以帮助我们检查重写方法的方法声明的正确性
注意事项:1、私有方法不能被重写(父类私有成员子类是不能继承的)
2、子类方法访问权限不能更低(public>默认>私有)
(9)Java中继承的注意事项
1、Java中类只支持单继承,不支持多继承
2、Java中类支持多层继承
(10)案例(教师和学生)
//父类Person
package Java150_168;
public class Person {
private String name;
private int age;
//构造方法
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//set,get函数
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//Person的派生类:Teacher
package Java150_168;
public class Teacher extends Person{
public Teacher() {
}
public Teacher(String name,int age) {
super(name,age);
}
public void teach() {
System.out.println("用爱成就每一位学员!\n");
}
}
//Person的派生类:Student
package Java150_168;
public class Student extends Person{
public Student(){
}
public Student(String name,int age) {
super(name,age);
}
public void study() {
System.out.println("好好学习,天天向上\n");
}
}
//测试类Demo
package Java150_168;
/*需求:定义老师和学生类,然后写测试代码;
最后找到老师类和学生类当中的共性内容,抽取出一个父类,用继承方式改写代码,并进行测试
*/
public class Demo {
public static void main(String[] args) {
Teacher t1=new Teacher();
t1.setName("林青霞");
t1.setAge(30);
System.out.println(t1.getName()+","+t1.getAge());
t1.teach();
Teacher t2=new Teacher("杨老师",32);
System.out.println(t2.getName()+","+t2.getAge());
t2.teach();
Student t3=new Student();
t3.setName("风清扬");
t3.setAge(33);
System.out.println(t3.getName()+","+t3.getAge());
t3.study();
Student t4=new Student("肖小恩",22);
System.out.println(t4.getName()+","+t4.getAge());
t4.study();
}
}
//Console输出:
林青霞,30
用爱成就每一位学员!
杨老师,32
用爱成就每一位学员!
风清扬,33
好好学习,天天向上
肖小恩,22
好好学习,天天向上
10、修饰符
(1)package(包)
文件夹,对类进行分类管理
定义格式:package 包名;(多级包用 . 分开)
(2)导包
使用不同包中的class类时,先导包:import 包名;
范例:import cn.itcast.Teacher
(3)修饰符
1、权限修饰符
2、状态修饰符(final最终态,static静态)
final
:1、被final修饰的方法是最终方法,不能被重写
2、被final修饰的变量即是一个常量了,不能再被赋值
3、被final修饰的类为最终类,不能被继承
final修饰基本类型,数据值不能变;修饰引用类型,地址值不能变,但地址里面的内容可以改变。
static
:可以修饰成员方法、成员变量
static修饰的特点:1、被类的所有对象共享
2、可以通过类名调用(建议),也可以通过对象名调用
访问特点:1、非静态成员方法:静态、非静态的成员方法+变量都可以访问
2、静态的成员方法:只能访问静态的成员方法+变量(静态成员方法只能访问静态成员)
11、多态
(1)概述
:同一个对象,在不同时刻表现出来的不同形态。
多态的前提和体现
:1、有继承/实现关系;2、有方法重写;
3、有父类引用指向子类对象(nimal a=new Cat();)
**(2)**多态中成员的访问特点
成员变量:编译看左边,执行看左边
成员方法:编译看左边,执行看右边
为何不一致?–>成员方法有重写,而成员变量没有。
**(3)**多态的好处和弊端
好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来使用的时候,使用具体的子类型参与操作
弊端:不能使用子类的特有功能(转型可以解决此弊端)
**(4)**多态中的转型
1、向上转型:从子到父,父类引用指向子类对象 Animal a=new Cat();
2、向下转型:从父到子,父类引用转为子类对象 Cat c=(Cat)a;
(两边不等价,强制执行的话,会出现ClassCastException异常)
**(5)**案例(猫和狗)
package j169_174;
//Animal类
public class Animal {
private String name;
private int age;
//构造方法
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
//get,set
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("动物吃东西");
}
}
package j169_174;
//Cat类,继承Animal类
public class Cat extends Animal{
//构造方法
public Cat() {
super();
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
package j169_174;
//Dog类,继承Animal类
public class Dog extends Animal{
//构造方法
public Dog() {
super();
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
package j169_174;
//测试类
public class AnimalDemo {
public static void main(String[] args) {
Animal a=new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
a=new Cat("加菲",5);
System.out.println(a.getName()+","+a.getAge());
a.eat();
Animal d=new Dog();
d.setName("旺财");
d.setAge(6);
System.out.println(d.getName()+","+d.getAge());
d.eat();
d=new Dog("旺财",6);
System.out.println(d.getName()+","+d.getAge());
d.eat();
}
}
12、抽象类
**(1)**概述:在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
**(2)**抽象类的特点
One、抽象类和抽象方法必须使用abstract关键字修饰
格式:public abstract class 类名{},public abstract void eat();
Two、抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
Three、抽象类不能实例化,可参照多态的方式,通过子类对象实例化,谓抽象类多态
Four、抽象类的子类:要么重写父类中所有抽象方法,要么也是抽象类
**(3)**抽象类的成员特点
1、可以有成员变量(变量/final常量)
2、构造方法:有,但是不能实例化,用于子类访问父类数据的初始化
3、成员方法:可以有抽象方法:限定子类必须完成某些动作
可有非抽象方法:提高代码复用性
**(4)**案例(猫和狗)
package j175_178;
//Animal类
public abstract class Animal {
private String name;
private int age;
//构造方法
public Animal() {
}
public Animal(String name,int age) {
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//抽象方法,吃饭
public abstract void eat();
}
package j175_178;
//Cat类,继承Animal类
public class Cat extends Animal{
public Cat() {
super();
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
package j175_178;
//Dog类,继承Animal类
public class Dog extends Animal {
public Dog() {
super();
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
package j175_178;
//AnimalDemo类
public class AnimalDemo {
public static void main(String[] args) {
Animal a=new Cat