一、封装
● 隐藏了实现细节,对外提供访问的方式。
● 如在以前的代码中,将属性直接定义在类中,用户在创建对象的时候,可以给属性任意赋值,如age,用户在创建对象的时候,赋值为-20,该值就是一个非法的值。 此时可以使用封装,对用户传进来的非法数值进行处理。
封装的步骤
1)、属性private
2)、对外提供get/set方法
3)、在方法中加入流程控制语句
封装特点
● 隐藏一个类的实现细节;
● 调用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
● 便于修改,增强代码的可维护性;
二、类
一般定义格式:
public class 类名{
变量;
构造方法;
其他方法;
}
对象得定义:
类名 对象名 = new 类名(参数列表);
注意点
1)、类
● 类的访问修饰符只有public和默认(default|friendly)两种
● 数组类的定义:
Student[] stuArr = new Student[5];//堆中开辟{null,null,null,null,null}
stuArr[0] = new Student();//然后再开辟一个学生类,让首元素指向它● 常见的空指针异常错误
比如一个引用数据类型,在每创建之前,会被自动赋初始值null,一般引用数据类型会包含很多方法,所以当引用数据类型没创建(即为null时)再调用相关方法,便会报这样的错误java. lang.NullPointerException,即未初始化变量
class Student{ int age; } public class Demo { public static void main(String[] args) { Student stu; System.out.println(stu.age); } } //报错java: 可能尚未初始化变量stu class Student{ int age; } public class Demo { public static void main(String[] args) { Student stu = new Student(); System.out.println(stu.age); } } //正确输出0
2)、构造方法
● 格式
修饰符 类名(参数列表){
初始化语句
}
● 方法名和类名相同;
● 没有返回值类型,不能有return语句;
● 不能被static,final修饰
● 类中即使自己不定义构造方法,也会存在一个默认的空的构造方法;若自己重新定义一个构造方法,便会使用自己定义的构造方法,原来的默认构造方法便会消失;所以当我们定义一个自己得构造方法时,一般还要添加一个空的构造方法来提高容错率;
● 可以存在多个构造方法(重载),会按对象创建得形式调用,构造方法之间还可以相互调用;构造方法还可以调用类中得其他方法;但其他方法不能调用构造方法;构造方法也不可以被对象调用;
● 构造方法是在对象被创建(new)的时候自动执行‘;
● 构造方法不能被继承
● 访问修饰符一般使用public,但没有强制性规定;
3)、this用法
● this:表示当前对象,可以通过this表示当前对象的属性方法等,可以区分成员变量和局部变量;
//比如 public class Person{ int age; public void setAge(int age){ this.age = age;//this就可以区分哪个是传进来的形参,哪个是对象的成员变量 } }
● 对象自己方法以及属性的调用:this.方法名(参数列表)、this.属性、this(参数列表)表示调用构造方法,但通过this调用的构造方法必须放在第一行(所以构造方法之间最多只能调用其他一个构造方法)
● this表示的是当前对象的地址
● 构造器中不能通过"this(形参列表)“的方式调用自身构造器如果一个类中声明了n个 构造器,则最多有 n - 1个构造器中使用了"this(形参列表)”
这里额外添加一个的易错点
public class test { public static void main(String[] args) { int i = 0; i = i++; System.out.println(i); } }
这里输出应该是什么?
答案是:0
可以这样理解:
先理解一个 i=0 的执行顺序;先加载一个数字0,再赋值给变量i;
所以可以先简单的理解 i=i++; 先把还是先加载一个数字,i原来的数字是0,所以先加载一个0(要赋值给i的,但目前并没有赋值),然后进行i++,此时i为1。这时,再将刚刚加载的0赋值给i。
这个地方理解的并不完全,可以上网查一下相关资料
三、导包
● 导包格式:import 包名
● package语句作为java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句, 则指定为无名包)。它的格式为:package xxx.xxx.xxx;
● 命名:通常用小写单词标识,通常使用所在公司网址的倒置。com.openlab(.www)
● 作用:
1.包帮助管理类,将功能相近的类放到一个包中;
2.便于管理类
3.解决类命名冲突问题
4.控制访问权限(default|friendly)
● 类中如何定义一个类名相同,包名不同的对象?
import a.Dog; //import b.Dog 报错,因为在之后定义Dog是分不清是哪一个Dog public class test { public static void main(String[] args) { Dog dog1 = new Dog();//gog1实现的是a包中Dog的功能 //如果还想定义一个Dog,但这个Dog在b包中,怎么办? //这是就可以这样:包名.类名 对象名 = new 包名.类名(参数列表) b.Dog dog2 = new b.Dog();//gog2实现的是b包中Dog的功能 } }
四、学生信息管理系统
注:这里只写了简单的例子,只包含了主要功能
学生类
package 学生信息管理系统;
public class StudentClass {
private int age;
private String name;
public StudentClass(String name, int age) {
this.age = age;
this.name = name;
}
public StudentClass() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
底层操作类
package 学生信息管理系统;
import java.util.Arrays;
import java.util.Scanner;
public class StudentBottom {
StudentClass[] studentClass = new StudentClass[0];
static int number = 0;
//添加
public void add(StudentClass stu){
StudentClass[] newClass = Arrays.copyOf(studentClass,studentClass.length+1);
newClass[newClass.length-1] = stu;
studentClass = newClass;
number++;
System.out.println("添加成功");
}
//删除
public void delete(int index){
if (index>=number&&index<0){
System.out.println("索引越界");
}else {
StudentClass[] newClass = new StudentClass[studentClass.length-1];
if (index!=0) {
System.arraycopy(studentClass, 0, newClass, 0, index);
}
if (index != studentClass.length-1){//12 3 45
System.arraycopy(studentClass,index+1,newClass,index,studentClass.length-index-1);
}
number--;
studentClass = newClass;
System.out.println("删除成功");
}
}
//修改
public void modification(int index){
if (index>=number&&index<0){
System.out.println("索引越界");
}else {
System.out.println("命名:"+studentClass[index].getName()+"年龄:"+studentClass[index].getAge());
System.out.println("请分别输入新的姓名和年龄");
String name = new Scanner(System.in).nextLine();
int age = new Scanner(System.in).nextInt();
studentClass[index].setName(name);
studentClass[index].setAge(age);
System.out.println("修改成功");
}
}
//查找
public void findStu(int index){
if (index>=number&&index<0){
System.out.println("索引越界");
}else {
System.out.println("命名:"+studentClass[index].getName()+"年龄:"+studentClass[index].getAge());
System.out.println("查找成功");
}
}
//遍历所有学生信息
public void foreach(){
System.out.println("学生姓名"+"\t"+"学生年龄");
for (StudentClass stu : studentClass){
System.out.printf("%4s\t\t%4d",stu.getName(),stu.getAge());
System.out.println();
}
}
}
实现类
package 学生信息管理系统;
import java.util.Scanner;
public class StudentView {
public static void menu(StudentBottom studentBottom, int choice){
switch (choice){
case 1:
System.out.println("--------添加--------");
System.out.println("请输入学生的姓名和成绩:");
String name = new Scanner(System.in).nextLine();
int age = new Scanner(System.in).nextInt();
studentBottom.add(new StudentClass(name,age));
break;
case 2:
System.out.println("--------删除--------");
System.out.println("请分别输入需要删除的索引");
int index = new Scanner(System.in).nextInt();
studentBottom.delete(index);
break;
case 3:
System.out.println("--------修改--------");
System.out.println("请输入需要修改的的索引");
break;
case 4:
System.out.println("--------查找--------");
System.out.println("请输入需要查找的索引");
break;
case 5:
System.out.println("--------遍历--------");
studentBottom.foreach();
break;
default:
System.exit(0);
break;
}
}
public static void main(String[] args) {
StudentBottom studentBottom = new StudentBottom();
while (true) {
System.out.println("请输入您的选择:0退出");
menu(studentBottom, new Scanner(System.in).nextInt());
}
}
}