前面已经提到过Java的对象和类,接下来我要记录的是Java的封装、继承和多态。
一、封装
封装是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰切不被利用。理解封装性的一个方法就是把它想成一个黑匣子,它可以阻止在外部定义的代码随意访问内部代码和数据。对黑匣子内代码和数据的访问通过一个适当的定义的接口严格控制。
这次学习的是访问控制修饰符,是体现封装性的一部分,它用于限制访问成员变量或常量的权限。访问控制修饰符有4个等级:private、protected、public、默认(不指定修饰符)。其中,用private修饰的变量称为私有变量,用protected修饰的变量称为受保护变量,用public修饰的变量称为公共变量,不加任何修饰符的变量称为默认变量。下图给出了修饰符的作用范围。
private是最严格的访问权限受它保护的成员变量只能被所属类访问,那么如果需要改变受private保护的变量就需要在该类写下get/set方法作为接口供其他类交流数据,下面就看这个例子
public static void main(String[] args) {
// TODO 自动生成的方法存根
Student s1=new Student();//创建一个学生对象s1
String namem="tom";int agem=15;
s1.Name=namem;
s1.setAge(agem); //用agem实参,值=15传入setAge方法
System.out.println(s1.Name); //打印学生名字
System.out.println(s1.getAge()); //打印学生年龄
}
}
class Student{
String Name;
private int Age;
void setAge(int age1) {
Age=age1; //把得到的值赋予成员变量Age
}
int getAge(){
return Age; //返回年龄
}
}
这里请注意Name和Age不同的调用方法,受private保护的变量为Age,只有Student类能访问Age变量,就是说private的作用域在整个Student类,附运行结果
主函数类名我没有给出,创建包和类的时候设置的,在主函数去访问无修饰的变量就可以直接访问,例如上面例子的Name的访问方法(对象名.成员变量)
另外两个修饰符暂时还没有例子来具体说明,了解它们的作用范围就行,不过要提到的一点是,在修饰类的时候一个Java程序有且只有一个public类。
二、继承
继承是面向对象程序设计中两个类之间的一种关系,是一个类可以继承另一个类(即它的父类)的状态和行为。被继承的类称为超类或父类,继承父类的类称为子类。一个父类可以有多个子类,子类继承父类的(成员)变量和(成员)方法,子类还能覆盖继承的方法。
关键字extends,例class A extend B{},B是A的父类
supper()方法,用于调用父类的构造方法。规则:
1.必须放在子类构造方法的第一句。
2.如果父类参数列表为空,则super可以省略。
3.super的参数列表必须和父类保持一致
下面我举个成员变量继承的例子
public class Pris {
public static void main(String[] args) {
// TODO 自动生成的方法存根
MiddleStudent s1=new MiddleStudent("tom",15,12);//创建一个中学生对象s1
//String namem="tom";int agem=15;
//s1.Name=namem;
System.out.println("姓名"+s1.Name); //打印学生名字
System.out.println("年龄"+s1.Age); //打印学生年龄
System.out.println("学号"+s1.Num); //打印学生学号
}
}
class Student{
String Name; //名字
int Age; //年龄
Student(String Name,int Age){ //构造方法
this.Name=Name; // 该类(this)的成员变量(Name) <= 参数得到的局部变量(Name)
this.Age=Age;
}
}
class MiddleStudent extends Student{ //Studenet是父类
int Num;
MiddleStudent(String Name,int Age,int Num){ //构造方法
super(Name,Age); //调用父类构造方法
this.Num=Num;
}
/*super();语句必须放在子类构造方法的第一条代码
* 如果父类构造方法空参,此句可省略
* 参数列表与父类构造方法参数列表必须一致*/
}
成员方法的调用与成员变量访问差不多,这里就不再多说,附上运行结果
三、多态
多态这个就比较简单,多态性可以用“一个对外接口,多个内在的实现方法”来表示。也就是说,我们可以在一个类中定义多个同名方法,程序在调用某个方法时,系统会自动根据参数类型和个数的不同调用不同的方法,这种机制被称为方法重载。如果在子类重新定义父类继承来的方法,就称为覆盖。
下面我为大家解读一下在实验课写的代码,题目是编写一个类Myclass,重载类的add方法实现当整数/浮点数/字符串类型时
1.返回两个整数的和
2.返回两个小数的和
3.返回两个字符串连接
public class Lab03 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in=new Scanner(System.in);
int i0,i1,i2;String s1,s2;double d1,d2;
Myclass m1=new Myclass();
System.out.println("请选择输入数据类型\n1.整型\t2.字符型\t3.浮点型");
i0=in.nextInt();
if (i0==1) {
System.out.println("请输入两个数据");
i1=in.nextInt();
i2=in.nextInt();
System.out.println(m1.add(i1,i2));
}
else if (i0==2) {
System.out.println("请输入两个数据");
in.nextLine(); //除去上次输入的回车符
s1=in.nextLine();
s2=in.nextLine();
System.out.println("s1="+s1+"\t"+"s2="+s2);
System.out.println(m1.add(s1,s2));
}
else if (i0==3) {
System.out.println("请输入两个数据");
d1=in.nextDouble();
d2=in.nextDouble();
System.out.println(m1.add(d1,d2));
}
else
System.out.println("error");
in.close();
}
}
class Myclass {
int add(int a,int b) {
return a+b;
}
String add(String a,String b) {
return a+b;
}
double add(double a,double b) {
return a+b;
}
}
用main函数作为测试,创建Myclass类的实例对象m1
Myclass m1=new Myclass();
然后判断用户需求传递相应的数据,调用相应的方法,举个求整数和例子
System.out.println("请输入两个数据");
i1=in.nextInt();
i2=in.nextInt();
接收用户输入的信息分别存放到i1,i2
m1.add(i1,i2)//调用add方法,传递i1,i2
函数有返回值,返回给系统打印函数直接打印
int add(int a,int b) {
return a+b;
}
接收到数据后直接返回两数的和
在主方法中还有一些分支语句,还有疑问的话欢迎来评论反馈。