封装
封装的优点
1. 良好的封装能够减少耦合。
2. 类内部的结构可以自由修改。
3. 可以对成员变量进行更精确的控制。(代码举例说明)
4. 隐藏信息,实现细节。
public class Person { //定义一个Person类 private int age; //前面我们将定义class的时候,我们这种写法就是java封装 private String name;//private访问修饰符,限定了name属性,只能在本类中去访问name属性的赋值,取值操作 public int getAge() { //方法的修饰符为public return age; } public void setAge(int age) { //因为对属性age年龄的赋值操作是通过这里的setAge方法来操作,所以在这里,作进一步的精确控制 if(age>0 && age<150) { this.age = age; }else { System.out.println("你输入的年龄不合法"); } } public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class TestMain { public static void main(String[] args) { Person person = new Person(); person.setAge(151);//调用setage方法 System.out.println(person.getAge());//输出调用getage方法 } }
类的继承
类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,通过类的继承关系,
使公共的特性能够共享,简化了对象、类的创建工作量,增加了代码的可重用性,复用性。
(1) 子类继承父类的成员变量
当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:
1)能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;
2)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。
(2) 子类继承父类的方法
同样地,子类也并不是完全继承父类的所有方法。
1)能够继承父类的public和protected成员方法;不能够继承父类的private成员方法;
2)对于子类可以继承的父类成员方法,如果在子类中出现了同名称且同参数的成员方法(又叫子类重写父类的方法),则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。
注意:隐藏和覆盖是不同的。隐藏是针对成员变量和静态方法的,而覆盖是针对普通方法的
public class Person { //定义一个Person类 private int age; //前面我们将定义class的时候,我们这种写法就是java封装 private String name;//private访问修饰符,限定了name属性,只能在本类中去访问name属性的赋值,取值操作 public String sex="男"; protected double height;//sex和height这两个属性会被子类继承 public int getAge() { //方法的修饰符为public return age; } public void setAge(int age) { //因为对属性age年龄的赋值操作是通过这里的setAge方法来操作,所以在这里,作进一步的精确控制 //this.age = age; if(age>0 && age<150) { this.age = age; }else { System.out.println("你输入的年龄不合法"); } } public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class Teacher extends Person {//这个写法,extends这个关键字的应用,就是为一个子类指定父类的实现语法 private String sex="女"; public String getSex() { //return this.sex;//输出女 //return sex;输出女 return super.sex;//输出男见主方法 } }
public class TestMain { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.height=1.7; System.out.println(teacher.height);//输出1.7 teacher.setName("张三"); System.out.println(teacher.getName());//输出张三 System.out.println(teacher.getSex());//输出女 子类会把父类的值隐藏 } }
3、子类是不能够继承父类的构造器,但是要注意的是,如果父类的构造器都是带有参数的,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。如果父类有无参构造器,则在子类的构造器中用super关键字调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。做个例子就清楚了:
public class Person { //定义一个Person类 String name; int age; //第二种方法 public Person() { System.out.println("Person父类的无参数构造器被执行了"); } //自定义一个构造器,一旦在类里显示的写出了构造函数,系统编译的时候,还会不会默认自动加上空构造 public Person(String name ,int age) { System.out.println("Person父类的有参数构造被执行了"); this.name = name; this.age = age; } }
public class Teacher extends Person {//这个写法,extends这个关键字的应用,就是为一个子类指定父类的实现语法 //这里报错,不能实现继承,就是因为,父类现在还没有无参数构造器 //第一种方法 在子类里,也没有写构造器,他不会继承父类的构造器,其次我们实例化对象的时候,子类会默认的去调用父类的无参数构造器 public Teacher() { super("李四", 30);//第一种方法 用super关键字去调用父类中的构造方法的写法,在子类的构造器里,显示的写出要调用的父类的具体构造器 //父类有无参数构造器,在子类的构造器中,就可以不用super关键字去调用父类的构造器, //如果说,你要显式地写出,注意,super必须写在子类的构造器的第一行 System.out.println("Teacher子类的构造器被执行了"); } }
public class TestMain { public static void main(String[] args) { Teacher teacher = new Teacher(); //结果Person父类的有参数构造被执行了 // Teacher子类的构造器被执行了 } }
4.super关键字
super主要有两种用法:
1)super.成员变量/super.成员方法;
2)super(parameter1,parameter2....)
第一种用法主要用来在子类中调用父类的同名成员变量或者方法;
第二种主要用在子类的构造器中显示地调用父类的构造器,
要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。