文章目录
封装 private继承 extends多态 abstract/interface/implements封装 private
封装是面向对象编程的基本特点之一,也是它最核心的思想
类的封装就是在定义一个类时,将类中的属性或方法私有化,就是使用private修饰符设置其访问权限,不让它们暴露在其他类的面前,这样其他类就不能直接访问和修改该类的内容,确保了数据的安全性(编程中坚持的理念是:能用private修饰,就绝对不去用public修饰)
类中被private关键字私有化的属性只能在它所在类中被访问,如果外界想要访问私有属性,需要通过该类的对外接口(即:事先定义好的public方法)来访问,如:设置属性值的setXx()方法和获取属性值的getXx()方法
class Teacher{private String name; //私有属性private int age;private void setAge(int age) {//私有方法this.age = age;}public void setName(String name,int age) {this.name = name;this.setAge(age);}//类内访问本类的私有属性和方法public String getNameAge() {System.out.print("我叫"+name+",今年"+age+"岁");return name;}}public class Person {public static void main(String[] args) {Teacher teach=new Teacher();teach.setName("俞敏洪",56); teach.getNameAge();}}输出结果打印:我叫俞敏洪,今年56岁
封装的好处?
1. 隐藏了类内部的具体实现,提高对象数据的安全性
2. 类内部的结构可以自由修改,不会对外界造成影响
3. 降低类之间的耦合度,减小类之间的相互影响
继承 extends
1.继承描述的是事物之间的所属关系
在java中,类的继承是指:在现有类的基础上构建一个新的类,构建出来的类被称为子类,现有类被称为父类,子类继承了父类的所有属性和方法,又可以定义自己的属性和方法,所以,子类是父类的扩展
class Person{String name;int age;public void eat(){System.out.println("每日三餐");}}class Teacher extends Person{public void teach(){System.out.println("教的科目是英语");}}public class Test {public static void main(String[] args) {Teacher teach=new Teacher();System.out.print(teach.name="马云,");System.out.println((teach.age=54)+"岁");teach.eat();teach.teach();}}输出结果打印:马云,54岁每日三餐教的科目是英语
2.java中,类仅允许单继承,不允许多重继承,即一个类只能继承一个父类
class Cat{}class Dog{}class WhiteDog extends Cat{} //单继承,合法class BlackDog extends Cat,Dog{} //多重继承,不合法
3.java中,不允许一个类继承多个父类,但允许多个类继承同一个父类
class Dog{}class WhiteDog extends Dog{} //合法class BlackDog extends Dog{} //合法
4.java,不支持多重继承,但支持多层继承,即:一个类的父类在去继承另一个父类,这样该子类就拥有了多个父类的成员(其实:在java中,子类和父类只是一个相对的概念,一个类在作为父类的同时,也可以是一个子类,如下面程序的Dog类)
class Animal{String name;}class Dog extends Animal{public void eat(){System.out.println("喜欢吃骨头");}}class BlackDog extends Dog{}public class Test {public static void main(String[] args) {BlackDog black=new BlackDog();System.out.print(black.name="白毛狗");black.eat();Dog dog=new Dog();System.out.print(dog.name="狗狗");}}输出结果打印:白毛狗喜欢吃骨头狗狗
继承的意义?
继承最大的一个作用就是提高了类的可重用性,省时省力高效!
子类能继承父类的的私有成员吗?
子类会继承父类的所有所有成员,只是这些继承过来的私有成员对子类是不可见的,但子类还是可以通过父类的定义好的public方法来操作它们。如下面这个程序,可以通过子类的实例对象向父类的私有List集合中添加元素;但若想直接在子类中使用父类的私有属性,就会出现编译错误,如下面程序中的printBook()方法
java官方文档上说,子类不能继承父类的私有成员,因为继承过来的东西不能在类中显示也就相当于没有继承,我们无法在子类中对这些成员进行操作,具体可参考继承帖子
class Person{private String name;private List list=new ArrayList<String>();public void addArrayList(String book){list.add(book);}public void print(){for(int i=0;i<list.size();i++){System.out.println(i+" "+list.get(i));}}}class Teacher extends Person{//下面这个方法会报错,无法通过编译/*public void printBook(){for(int i=0;i<list.size();i++){System.out.println(i+" "+list.get(i));}}*/}public class Test {public static void main(String[] args) {Teacher teach=new Teacher();teach.addArrayList("java");teach.addArrayList("php");teach.addArrayList("数据结构");teach.print();}}输出结果打印:0 java1 php2 数据结构
重写父类方法?重写父类方法的意义?
子类继承了父类的方法,但可能父类的某个方法所实现的操作不是子类想要的,这时候,就可以在子类中对父类的方法进行重写,将父类方法的操作改成子类想要的操作
注意:
1.子类重写的方法和父类被重写的方法具有相同的返回值,方法名,形参列表
2.子类重写父类方法时使用的修饰符不能比父类被重写方法的修饰符更严格,可以一样。如:父类被重写方法用的是public,子类重写该方法时就不能用private来修饰
3.子类对象调用重写方法时,调用的是子类的方法,而不是父类中被重写的方法,想要调用父类被重写的方法,则必须使用super关键字来调用
4.声明为static,private或final的方法不能被重写,还有构造方法也不能被重写
class Animal{String name;public void eat(){System.out.println(name+"喜欢吃");}}class Dog extends Animal{public void eat(){super.eat(); //此句用于调用父类被重新方法System.out.println(name+"喜欢吃骨头");}}public class Test {public static void main(String[] args) {Dog dog=new Dog();dog.name="白毛狗";dog.eat();}}输出结果打印:白毛狗喜欢吃白毛狗喜欢吃骨头
扩展: 重写与重载的区别?
重载:在同一个类中有两个或两个以上的方法,拥有相同的方法名,但是参数列表不相同(参数个数/参数位置/参数类型不一致),最常见的重载的例子就是类的构造函数
重写:子类的方法覆盖父类的方法,叫重写
1.子类重写的方法和父类被重写的方法具有相同的返回值,方法名,形参列表
2.子类重写父类方法时使用的修饰符不能比父类被重写方法的修饰符更严格
多态 abstract/interface/implements
抽象方法
1.被abstract关键字修饰,且不含方法体(即:方法中没有{})的方法被称为抽象方法
注:抽象方法必须同时满足上面两个条件
抽象类
1.含有抽象方法的类必须声明为抽象类,抽象类必须使用abstract关键字修饰,否则无法通过编译
2.抽象类不能使用new关键字来创建实例对象
3.抽象类的主要作用是被子类继承,通过子类来使用其内部数据
注意:子类继承了抽象父类,那么就必须覆盖父类的所有抽象方法后,才能创建对象,不然也要使用abstract关键字声明为抽象类,这时候该子类也不能创建对象了,就又得通过其它新类来继承该子类才能在外界使用它们的数据,但这样,该子类的意义就不大了,所以一般继承父类后都会覆盖父类中的所有抽象方法
注意:子类覆盖父类的抽象方法时,这些方法的访问权限必须和父类中这些方法的访问权限一样或更加宽松,比如父类的某个抽象方法被声明为public,那么子类覆盖了这个抽象方法后就不能声明为protected或private。并且子类覆盖的方法和父类被覆盖的方法具有相同的返回值,方法名,形参列表
abstract class Person{String name;abstract void setJob(String job);abstract void setAge(int age);}//父类中有两个抽象方法,所以子类也必须实现这两个方法class Teacher extends Person{@Overridevoid setJob(String job) {System.out.println(name+"是个"+job);}@Overridevoid setAge(int age) {// TODO Auto-generated method stub}}class Student extends Person{@Overridevoid setJob(String job) {System.out.println(name+"是个"+job);}@Overridevoid setAge(int age) {// TODO Auto-generated method stub}}abstract class Worker extends Person{//子类覆盖父类方法的权限比父类更严格,无法通过编译,//除非将子类声明为抽象类 或者 另外覆盖父类抽象方法public void setJob(){System.out.println("子类覆盖父类方法的权限比父类更严格,无法通过编译,"+ "除非将子类声明为抽象类 或者 另外覆盖父类抽象方法");}}public class Test {public static void main(String[] args) {Teacher t=new Teacher();t.name="赖红";t.setJob("老师");Student s=new Student();s.name="蔡栋";s.setJob("学生");//Worker w=new Worker(); //此处报错,抽象类无法创建对象}}输出结果打印:赖红是个老师蔡栋是个学生
接口
3.java中不允许类的多继承,为了解决这一局限性,就有了接口的产生,java中允许类实现多个接口 也允许接口继承多个接口
2.接口是一种特殊的抽象类,接口里面的方法都默认为public abstract修饰,接口里面没有变量,接口的属性只能时默认为public static final修饰的常量
3.因为接口是个特殊的抽象类,不能用来创建实例对象,所有接口里面的方法需要通过接口的实现类(接口的子类)来完成,并且实现类必须重写接口里面的所有方法
4.接口默认为public修饰,接口中的所有常量和方法也都默认为public修饰,所以子类在实现接口中的方法时也必需使用public修饰(访问权限不能比它们更严格)
5.接口的定义通过interface关键字来完成而不是class关键字(但生成的是.class文件),接口的实现通过implements关键字来完成
//接口默认为public修饰,所以接口中的常量和方法也都是默认为public修饰interface Biology{//这是个常量,因为默认为public static final修饰String NEED_ENERGY="需要能量";//这是个抽象方法,默认为public abstract修饰void exist();}interface Plant {void life();} //接口是一个特殊的类,所以接口也可以继承接口interface Human extends Biology{void run();}//实现接口,实现接口就必须实现接口中的所有方法class Teacher implements Human{@Overridepublic void exist() {System.out.println("老师的生命活动"+NEED_ENERGY);}@Overridepublic void run() {System.out.println("老师经常去做跑步");}}class Tree{String breathe;}//可以在继承类的同时实现接口,并且可以实现多个接口class AppleTree extends Tree implements Plant,Biology{@Overridepublic void life() {System.out.println("树不能自由移动"+breathe);}@Overridepublic void exist() {System.out.println("树的生命活动也需要能量");}}public class Test {public static void main(String[] args) {Teacher t=new Teacher();t.exist();t.run();AppleTree aTree=new AppleTree();aTree.breathe="吸收二氧化碳,释放氧气";aTree.life();aTree.exist();}}输出结果打印:老师的生命活动需要能量老师经常去做跑步树不能自由移动吸收二氧化碳,释放氧气树的生命活动也需要能量
接口的意义?
1.规范性:
接口是一种规范,它规定接口中要被实现的功能,然后交给实现类来实现
2.高效性和维护性:
接口实现了功能的定义与实现分离特点。在一些大型团队项目中,接口的这一特点有利于队员之间的合作,而且代码会更显得层次分明,有利于后期的代码维护
2.松耦合:
接口实现了功能的定义与实现分离特点,减小类之间的相互影响
3.安全性:
接口只描述了要实现的功能,但不涉及任何具体的细节
多态
多态是同一件事物具有多个不同表现形式或形态的能力
多态存在的三个必要条件???
1. 继承
2. 重写
3.向上转型(父类引用指向子类对象–>Person p=new Teacher();)
多态的定义和使用格式
父类类型 变量名 = new 子类类型();
变量名.方法名();
注意:使用多态方式调用方法时,应先检查要调用的方法父类中是否存在,不存在则会出现编译错误
interface Person{void Task();}class Teacher implements Person{@Overridepublic void Task() {System.out.println("老师的任务是教书!");}}class Student implements Person{@Overridepublic void Task() {System.out.println("学生的任务是学习!");}}public class Test {public static void main(String[] args) {//多态的定义Person p1=new Teacher(); //使用通过一个父类类型的变量来引用一个子类类型的对象Person p2=new Student();//多态的使用p1.Task(); //使用多态方式时,不能通过父类的变量去调用子类特有的方法p2.Task();}}输出结果打印:老师的任务是教书!学生的任务是学习!
多态的优点
多态不仅解决了方法的同名问题,还是程序变得更加灵活,从而有效地提高程序的可扩展性和可维护性
多态的缺点
不能调用子类特有的方法
推荐
封装的作用
私有成员能否被继承
接口
接口的作用
java官方文档