您的位置:首页 > 其它

#码神心得_08# 面向对象三大特征——封装、继承、多态

2016-06-17 15:18 676 查看

封装、继承、多态

面向对象的三大特征:封装、继承、多态,对于之前的我来说一直是很模糊的概念,直到余老师的讲解,终于有了较为深入的理解。

一、封装

        顾名思义,“封装”就是把某些“东西”的具体“细节”封装隐藏起来,不让其他无关的“事物”随便动用,只留出“公用”部分与外界发生联系。比如说:一台手机,只提供屏幕的接触功能和按键功能供你操作,而手机内部的所有细小的零件全部都包装在里面不让你去动用,这样更能保持手机内部资料结构不会被随意破坏。

        在java中,最小的单位是“类”,再类中是的数据和对数据的操作集合在一起,从而对使用该类的其他人来说,可以不管他的实现方法,而只管用它的功能,从而实现所谓的信息隐藏。

        封装的好处:1、实现了专业的分工             2、隐藏了细节信息

        在这里自然要讲到访问控制修饰符——private:只能在当前类中访问。对于大多数情况下来说,成员变量都要使用private修饰,防止其他类对其的直接获取,而是通过get(),set()对成员变量进行获取与修改,这样才体现了java面向对象良好的封装性。

二、继承(extends)

        对于拥有许多相同属性或方法的各个类,使用继承,可以大大减少代码的重复。

        比如:狗、猫、猪三个类,都拥有相同的属性:一张嘴、两只耳朵、四条腿。而且都能进行奔跑();这种情况下如果每个类都去声明属性和方法的话,代码重复性就很大。如果声明一个拥有这些属性的动物类,然后狗、猫、猪都继承它,那么就只需要在动物类声明这些属性和方法,子类自需要调用父类的属性方法即可,大大实现的代码的复用。

        一下说明几点细节:

        1、java的继承为单继承

        2、使用 extends 关键字进行继承

        3、父类方法重写:当子类声明了一个与父类相同的方法时(方法名和参数类型都相同),父类的方法将会被覆盖

        4、super关键字:调用父类属性或方法

        5、只有在子类的构造方法里面才可以调用父类的构造方法super(),而且必须是在第一行调用

        6、不要在父类构造器中调用子类重写方法:因为程序首先是执行父类构造方法,而此时子类并没有完成初始化,此刻调用子类方法会出现空指针问题。

        7、@Override:对于在子类重写的父类方法,加上@Override会使程序阅读性提高

三、多态

        多态分为编译时多态与运行时多态,例如:方法的重载为编译时的多态,而对于继承与覆盖的方法,java运行时系统会根据调用该方法的实例的类型来决定选择调用哪个方法,称为运行时多态。

        理解:

        1、子类以父类的身份出现时,做事情还是使用子类的属性和方法。而且此时子类类型需要向上转型,由jvm自动实现

        2、父类以子类的身份出现时,需要进行引用数据类型强制转换,同时无法使用子类中特有的属性和方法

        多态的好处:实现方法的重写与重载

四、初始化块

        在有初始化块的程序中,执行顺序为:

        1、静态初始化块

        2、普通初始化块

        3、构造方法

        4、普通方法

课堂作业

定义普通人、老师、班主任、学生、学校这些类,提供适当的成员变量、方法用于描述其内部数据和行为特征,并提供主类运行。要求尽量抽象,封装好各个对象的职责。

场景1:学生在学校上课

场景2:老师给学生布置作业

场景3:班主任要求学生参加学校的文体比赛

Person类

public class Person {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}


Student类

public class Student extends Person {

Student(String name) {
setName(name);
}
//学生在某学校上课
public void study(School s) {
System.out.println("学生" + getName() + "在" + s.getSchoolName() + "上课");
}

}


Teacher类

public class Teacher extends Person {
Teacher() {
}

Teacher(String name) {
setName(name);
}
//老师给某学生布置作业
public void setHomework(Student s) {
System.out.println(getName() + "老师给学生" + s.getName() + "布置作业");

}
}


MainTeacher类(班主任)

public class MainTeacher extends Teacher {

MainTeacher(String name) {
setName(name);

}
//班主任要求某学生参加某学校的比赛
public void joinCompetition(Student s, School sc) {
System.out.println(getName() + "班主任要求学生" + s.getName() + "参加" + sc.getSchoolName() + "的"+sc.getCompetition());
}
}


School类

public class School {
private String schoolName;
private String competition;

School(String name) {
setSchoolName(name);
}

public String getCompetition() {
return competition;
}

public void setCompetition(String competition) {
this.competition = competition;
}

public void setSchoolName(String name) {
this.schoolName = name;

}

public String getSchoolName() {
return schoolName;
}

}


测试类Test

public class Test {

public static void main(String[] args) {

School school = new School("清华大学");
school.setCompetition("羽毛球比赛");

Student student = new Student("小红");
student.study(school);

Teacher teacher = new Teacher("李四");
teacher.setHomework(student);

MainTeacher mainTeacher = new MainTeacher("张三");
mainTeacher.joinCompetition(student, school);
}

}


运行截图:



说明:

其中Teacher类、MainTeacher类、Student类继承Person类,Person类有一个属性name,子类都通过get()和set()调用name

Teacher类:setHomework(Student s):布置作业

MainTeacher类:joinCompetition(Student s, School sc):让学生参加活动

Student类:study(School s):上课

School类:setCompetition(String competition):设置比赛
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息