300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 封装 继承和多态以及抽象类和接口

封装 继承和多态以及抽象类和接口

时间:2021-11-03 19:10:48

相关推荐

封装 继承和多态以及抽象类和接口

目录

1、类与类成员的访问修饰符和其他修饰符

2、封装

3、继承的实现

4、多态——方法覆盖与方法重载

5、最终类

6、抽象类和抽象方法

(1)抽象类和抽象方法

(2)继承抽象类

(3)接口的概念与定义

(4)接口的实现

(5)抽象类和接口的区别及应用

摘要:本文主要说明了Java中类的封装、继承和多态的创建方法及其具体意义,以及抽象类和接口的具体含义和使用方法

1、类与类成员的访问修饰符和其他修饰符

Java通过访问修饰符来控制类的属性和方法 的访问权限以及其他功能,一般放在语句的最前端。分为访问修饰符和非访问修饰符。访问修饰符可用来保护对类、变量、方法以及构造方法的访问,分为以下四种:

public(公共的):访问权限最低,所以类都可以访问

default(缺省的):在当前包内可以访问

protected:当前类和它的子类可以访问

private:访问权限最高,仅当前类可以访问

2、封装

封装就是将代码的过程和数据隐藏起来避免外界直接访问,优点是可以隐藏私有数据,让使用者只能通过公用的方法来访问这些数据,大大的便利的数据的检查,有利于保护对象信息的完整性。此外还便于修改代码,提高维护性。JAVA中通过关键字private来实现封装。通过降低代码的访问权限来保护代码的完整性。

public class Main {public static void main(String[] args) {Person p1=new Person();Person p2=new Person();p1.SetNumber("014027");p2.SetNumber("2000000000");p1.SetName("张三");p2.SetName("李四");p1.SetAge(20);p2.SetAge(20);System.out.println("赋值后,对象p1的学号:"+p1.GetNumber()+",姓名:"+p1.GetName()+",年龄:"+ p1.GetAge());System.out.println("赋值后,对象p2的学号:"+p2.GetNumber()+",姓名:"+p2.GetName()+",年龄:"+ p2.GetAge());}}class Person{private String number;private String name;private int age;public Person(){number="113029";name="张三";age=20;}public void SetNumber(String number) {this.number = number;}public String GetNumber(){return number;}public void SetName(String name){this.name=name;}public String GetName(){return name;}public void SetAge(int age){this.age=age;}public int GetAge(){return age;}}

输出结果为

赋值后,对象p1的学号:0114027,姓名:张三,年龄:20

赋值后,对象p2的学号:20000000000,姓名:李四,年龄:20

3、继承的实现

继承就是子类继承父类的特征和行为,使子类对象同时具有父类对象的特征,同时子类继承父类的方法,在子类中无需定义即可调用父类中存在的方法。继承的意义在于,大大提高了需要重复使用旧代码的效率,能够极大缩短开发周期,降低开发费用。继承是除组合外提高代码重复使用效率的主要方法。

继承的主要作用在于在已有的基础上继续进行功能的扩充,使用extends关键字来实现。

public class Main {public static void main(String[] args) {Person p=new Person("张三","男",20);//创建对象p,同时利用提供的带参构造方法初始化类Person的成员变量p.print();//调用自定义方法print输出结果Employee p1=new Employee("李四","男",20,"重庆人文科技学院","重庆");p1.print1();}}class Person {//在同一模块内类的声明有没有public并不重要String name;//protected当前类和子类可以访问String sex;int age;public Person(){ }//提供一个默认的构造方法,否则在子类会编译不通过public Person(String name,String sex,int age){//带参数的构造方法,目的是给类中的属性(成员变量)初始化//注意——类的构造方法不需要返回值,如果有返回值会报错!!!!this.name=name;this.sex=sex;this.age=age;}public void print(){//自定义方法print,目的是输出成员变量的值System.out.println("姓名:"+this.name);System.out.println("性别:"+this.sex);System.out.println("年龄:"+this.age);}}class Employee extends Person{//子类Employee使用extends继承父类PersonString department;String positon;public Employee(String name,String sex,int age,String department,String positon){//带参构造方法,初始化子类和父类的成员变量this.name=name;this.sex=sex;this.age=age;this.department=department;this.positon=positon;}public void print1(){//新建方法print1,输出成员父类和子类的成员变量System.out.println("姓名:"+this.name);System.out.println("性别:"+this.sex);System.out.println("年龄:"+this.age);System.out.println("单位:"+this.department);System.out.println("位置:"+this.positon);}}

输出结果:

姓名:张三

性别:男

年龄:20

姓名:李四

性别:男

年龄:20

单位:重庆人文科技学院

位置:重庆

上述代码中,子类Employee继承了父类 Person的name,sex,age属性,因此子类的方法print1可以直接调用其属性,同时子类在父类的基础上新增了属性department和position,实现了功能的拓展,如果在进行开发时,可以节约很多时间和内存资源。

4、多态——方法覆盖与方法重载

覆盖发生在父类和子类之间,当子类与父类的成员变量同名时,子类的成员变量会隐藏父类的成员变量,当子类与父类的成员方法拥有相同的名字、参数列表、返回值类型时,子类的方法会重写父类的方法,也叫方法的覆盖。

public class Main {public static void main(String[] args) {Employee p1=new Employee("张三",4000);p1.Print();System.out.println("p1.salary="+p1.salary);Manager p2=new Manager("李四",8720.5,"组织部");p2.Print();System.out.println("p2.salary="+p2.salary);Manager p3=new Manager("王五",9786.4,"市场部");p3.Print();System.out.println("p3.salary="+p3.salary);}}class Employee{//父类String name;int salary;//父类定义salary成员变量public Employee(){ }//无参构造方法public Employee(String name,int salary){//带两个参数的构造方法this.name=name;this.salary=salary;}public void Print(){//无参无返回值方法,有输出语句System.out.println("员工姓名:"+name+",员工工资:"+salary);}}class Manager extends Employee{//Manager继承父类Employeedouble salary;//子类也定义了成员变量salary,此时隐藏父类的salary成员变量String department;//子类新定义的成员变量public Manager(){ };//子类的无参构造方法public Manager(String name,double salary,String department){//带三个参数的构造方法this.name=name;this.salary=salary;this.department=department;}public void Print(){//这里重写了父类的Print方法System.out.println("经理姓名:"+name+",经理部门:"+department+",经理工资:"+salary);}}

输出结果:

员工姓名:张三,员工工资:10000

p1.salary=10000

经理姓名:李四,经理部门:营销部,经理工资:12000.4

p2.salary=12000.4

经理姓名:王五,经理部门:研发部,经理工资:14872.3

p3.salary=14872.3

上述代码中,子类继承父类的同时,定义了一个与父类同名的成员变量salary,方法Print,此时在子类中父类的成员变量salary就被隐藏起来了,父类的方法Print被子类覆盖(重写),子类对象在调用时会忽略父类的salary成员变量和Print方法,这时发挥作用的是子类的salary变量和重写后的Print方法,这就是覆盖。覆盖发生有以下三点必要条件:

1、发生在父类与子类之间

2、必须具有相同的方法名,相同的返回值类型,相同的参数列表

3、重写的方法不能比别重写的方法的访问权限更低

另外,私有方法不能被覆盖,构造方法不能被覆盖,静态的方法不存在覆盖。

5、最终类

有一些类,在定义的时候就被设置为只能让使用者直接使用该类里面的功能,而不能 被继承,这种类就是最终类。最终类用关键字final修饰。所以,被final修饰的类不能被 继承,不能作为其他类的父类,典型代表就是String类。String类只能让我们直接使用该 类里面的功能。

6、抽象类和抽象方法

(1)抽象类和抽象方法

用abstract来修饰的类叫做抽象类,抽象类是它所以子类的公共属性的集合,包含一个或多个抽象方法的类。面向对象领域,抽象类主要用来进行类型隐藏,抽象类不能创建实例。

抽象类里面包含一般方法和抽象方法,抽象方法定义时直接在方法头后加分号,没有方法体,一般方法则拥有用大括号括起来的方法体。抽象方法必须存放在抽象类中,且只有方法头的声明,用分号来代替方法体的定义,即只定义成员方法的接口形式,没有具体操作。

子类继承父类的抽象方法以后,再使用不同的语句和方法体来重新定义它,形成多个方法名、返回值、参数列表都相同但是具体实现功能都不相同的方法。抽象类中定义抽象方法的目的是实现一个接口,使得所以的子类对外都呈现一个同名的方法,但是各自实现的功能都不相同。

(2)继承抽象类

因为抽象类不能直接被实例化,因此需要创建一个指向自己的对象引用(子类)来实例化。

public class Demo1 {public static void main(String[] args) {Animal p=new cat();//抽象类不能实例化,创建对象时new子类catp.play();//调用cat类的方法p=new dog();//多态p.play();//调用dog类的方法}}abstract class Animal{//定义了抽象类Animal用abstract关键字修饰public abstract void play();//定义了抽象方法play用abstract关键字修饰}class cat extends Animal{//子类cat,继承了父类Animal,重写了父类的方法public void play(){System.out.println("猫爬树");}}class dog extends Animal{//子类dog,继承了父类Animal,重写了父类的方法public void play(){System.out.println("狗撒欢");}}

输出结果:

猫爬树

狗撒欢

上述代码可以看出,抽象类Animal不能直接实例化,创建对象是不能使用"Animal p=new Animal()",两个子类调用的play方法并非父类的抽象方法play,实际调用的是继承实现类(子类cat和dog)继承的方法,这里继承的方法是实现了的抽象方法。这里定义对象的语句“Animal p=new cat();”叫做上转型处理方式,另外,抽象类必须拥有子类,且一个子类只能继承一个抽象类,另外,子类必须覆盖抽象类中的全部抽象方法(全部重写),否则子类也必须用abstract来修饰。

(3)接口的概念与定义

接口(interface)是一系列方法的声明,是一些方法特征的集合,接口只有方法的特征而没有方法的实现,这些方法在不同的地方被不同的类来实现不同的功能。接口就是抽象方法的集合,用关键字interface来进行声明。

接口定义的一般形式为

[访问控制符] interface <接口名>{

类型标识符 final 符号常量名 N =常数;

返回值类型 方法名(参数列表);

}

接口和类属于不同的概念,类描述对象的属性和方法,接口则包含抽象方法。接口的主要功能如下:

1、通过接口实现不相关类的相同行为

2、通过接口指明多个类需要实现的方法

3、通过接口了解对象的交互界面

(4)接口的实现

接口不能实例化,但是可以被实现。如果接口被一个类实现,。那么这个类必须实现接口中所以的抽象方法,否则这个类就必须用abttract修饰为抽象类。当有两个及以上类拥有相同的方法,但实现功能不一样时,可以定义一个接口,将这个方法提炼出来,在需要使用该方法的类中去实现,从而避免多个类定义系统方法的繁杂。例:

public class Demo3 {public static void main(String[] args) {//Eat p=new Eat();错误用法,接口不能被实例化Wolf p1=new Wolf();//定义Wolf类的对象p1Sheep p2=new Sheep();//定义Sheep类的对象p2p1.eat();//调用Wolf类的eat方法p2.eat();//调用Sheep类的eat方法}}interface Eat {//定义接口Eatvoid eat();//抽象方法}class Wolf implements Eat{//实现抽象方法的类1public void eat(){//重写的抽象方法1System.out.println("狼吃羊");}}class Sheep implements Eat{//实现抽象方法的类2public void eat(){//重写的抽象方法2System.out.println("羊吃草");}}

输出结果:

狼吃羊

羊吃草

另外,Java中,接口类型还可用来声明变量,它们可以成为一个空指针(null),或是绑定在一个以此接口实现的对象上。例:

/*public class Demo3 {public static void main(String[] args) {//Eat p=new Eat();错误用法,接口不能被实例化Wolf p1=new Wolf();//定义Wolf类的对象p1Sheep p2=new Sheep();//定义Sheep类的对象p2p1.eat();//调用Wolf类的eat方法p2.eat();//调用Sheep类的eat方法}}*/public class Demo3 {public static void main(String[] args) {//Eat p=new Eat();错误用法,接口不能被实例化//Wolf p1=new Wolf();//定义Wolf类的对象p1//Sheep p2=new Sheep();//定义Sheep类的对象p2//p1.eat();//调用Wolf类的eat方法//p2.eat();//调用Sheep类的eat方法Eat p=null;//接口类型声明一个变量pp=new Wolf();//Wolf类产生对象Wolfp.eat();//调用Wolf类的eat方法p=new Sheep();//Sheep类产生对象Sheepp.eat();//调用Sheep类的eat方法}}interface Eat{//定义接口Eatvoid eat();//抽象方法}class Wolf implements Eat{//实现抽象方法的类1public void eat(){//重写的抽象方法1System.out.println("狼吃羊");}}class Sheep implements Eat{//实现抽象方法的类2public void eat(){//重写的抽象方法2System.out.println("羊吃草");}}

输出结果:

狼吃羊

羊吃草

上例中,同一个接口变量p执行了不同类的方法,实现了Java的多态。

(5)抽象类和接口的区别及应用

抽象类和接口都不能被实例化,接口可以说说一直特色的抽象类,接口中的所以方法都必须是抽象的。接口中的方法默认定义为 public abstract 类型,接口的成员变量类型默认为 public static final 。接口和抽象类的区别具体见下表

从表中可以看出,接口的抽象程度比抽象类更高。通常抽象类的本体是抽象,接口的行为是抽象,意思是抽象类表示“是一个(is-a)”关系的抽象,接口表示“能(can-do)”关系的抽象。即关注一个事物本身是用抽象类,关注一个操作行为时用接口。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。