关于java的面向对象的编程特性中的封装机制,面向对象的特征:继承、封装和多态
00-1010 1.封装1。导言2。对封装3的理解和好处。实施步骤2。传承1。导言2。继承的基本语法3 .超级关键词1。基本介绍2。基础语法3。细节和好处。Super和this 4的比较。方法重写1。基本介绍2。注意事项和使用细节3。重载和重写的具体实施例1。方法的多态性2。对象的多态性(重点)3。多态1的注释和细节。多态性的先决条件2。属性3 .实例4。多态性5的向上转化。多态性6.Java动态结合机制7的向下转换。多态数组多态参数
目录
00-1010封装是指抽象的属性和方法的封装。数据在内部受到保护,程序的其他部分只能通过授权的方法对数据进行操作。
00-1010隐藏实现细节可以验证数据,保证安全性和合理性。
00-1010私有化一个属性提供一个public set方法,用来判断和赋值一个属性,和一个public get方法,用来获取属性public class student { private double score;void set score(double score){//这里也可以判断属性。分数=分数;} public Double get score(){ return score;}
00-1010
1.封装
继承可以解决代码重用。当多个类具有相同的属性和方法时,我们可以从中抽象出父类,然后在父类中定义这些相同的属性和方法,这样所有的子类就不再需要定义这些相同的属性和方法,只需要使用extends关键字继承父类即可。
00-1010 public class graduate extends student { }子类将自动拥有父类定义的属性和方法。父类也叫基类,超类子类也叫派生类。
00-1010子类继承父类的所有属性和方法,但是私有属性和方法不能在子类中直接访问,所以要通过公共方法访问。
包com . Wang . extend;public student {//父类public int age公共字符串名称;私人双分;弦乐爱好;public Double get score(){ return score;}包com . Wang . extend;Classgraduate扩展学生{//子类public wody test(){//子类不能直接访问私有属性。要调用public方法,get System.out.println(大学生姓名年龄爱好get score());}}子类必须调用父类的构造函数来完成父类的初始化。创建子类对象时,无论使用子类的哪个构造函数,默认都会调用父类的无参数构造函数。如果没有父类的无参数构造函数,则必须在子类构造函数中使用super()来指定使用父类的哪个构造函数来完成父类的初始化,否则编译会失败。
包com . Wang . extend;public student {//父类public int age公共字符串名称;//public Student(){//} public Student(int age,String name){ this . age=age;this.name=name}包com . Wang . extend;公共课研究生延伸学生{ public Graduate(){//super();//默认会有一个方法super()调用父类的无参数构造。//如果父类没有无参数构造函数,则必须指定哪个构造函数与super()一起使用
super(20,"小明"); }}super()在使用时,需要放在第一行。
super()和this()都只能放在构造器第一行,因此这两个方法不能同时存在于同一个构造器。
Java所有的类都是Object的子类。查看类的层级Ctrl+H。
父类构造器的调用不限于直接父类!将一直向上追溯到Object类(顶级父类)。
子类最多继承一个父类,java的单继承机制。
不能滥用继承,子类和父类要符合包含关系。比如,大学生包含在学生当中,这是学生就可以是父类,大学生为子类。
3.super关键字
1.基本介绍
super代表的是父类的引用,用于访问父类的属性,方法,构造器
2.基本语法
1.访问父类的属性/方法,但不能访问父类的private属性/方法
super.属性名; super.方法名(形参列表);
2.访问父类的构造器
super(形参列表);//只能放在构造器的第一句
3.细节与好处
1.父类属性由父类初始化,子类的属性子类初始化,分工明确。
2.当子类与父类的成员重名时,若要访问父类的成员,必须通过super。
3.super的访问不限于直接父类,当多个基类都有同名的成员,使用super访问时遵循就近原则。
4.super与this的比较
区别点thissuper访问属性先访问本类的属性,若本类没有再去父类只访问父类的属性调用方法先访问本类的方法,若本类没有再去父类直接访问父类的方法调用构造器调用本类的构造器,必须放第一句调用父类的构造器,必须放第一句特殊表示当前对象表示子类访问父类对象
4.方法重写
1.基本介绍
子类的一个方法与父类的名称,返回类型,形参列表都一样,称子类是父类方法的重写。
2.注意事项与使用细节
1.子类方法的返回类型与父类方法的返回类型相同或者父类返回类型的子类。
//正确示例public Object a() //父类返回类型为Objectpublic String a() //子类返回类型为String或者Object//Object是String的父类
2.子类方法不能缩小父类方法的访问权限。
//接下来是错误示例void display() //这是子类 子类访问权限为 默认的public void display() //这是父类 父类访问权限为public//public->默认的 访问权限变小所以报错
3.重载与重写的比较
名称发生范围方法名形参列表返回类型修饰符重载本类必须相同参数类型,个数或者顺序中至少有一个不同无要求无要求重写父子类必须相同必须相同子类的返回类型相同或者是父类的返回类型的子类不能缩小父类的访问范围
3.多态
1.基本介绍
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
2.具体体现
1.方法的多态
重写和重载体现多态。
//重载public int sum(int a,int b);public int sum(int a,int b,int c);//重写class A{ public void say(){ System.out.printf("A是父类~");}}class B extends A{ public void say() { System.out.printf("B是子类~");}}
2.对象的多态(重点)
一个对象的编译类型和运行类型可以不一致。编译类型在定义对象时,就确定了,不能改变,运行类型可以变化。定义时 = 的左边是编译类型,右边是运行类型。
Animal animal = new Dog();//Animal是编译类型,Dog是运行类型animal = new cat();//编译类型不能改变,运行类型可变
3.多态注意事项和细节讨论
1.多态的前提
两个对象(类)存在继承关系。
2.属性
没有重写,属性的值是看编译类型。
public class Tes { public static void main(String[] args) { A a = new B(); System.out.println(a.n); //这里输出的是10,因为属性的值要看编译类型,a的编译类型为A,所以输出的是A的属性 }}class A { public int n = 10;}class B extends A { public int n = 20;}
3.instance of
比较操作符,是用来判断对象的运行类型是否为某类型或者某类型的子类型。
4.多态的向上转型
本质:父类的引用指向了子类的对象。语法:父类类型 引用名 = new 子类类型();特点:可以调用父类中的所有成员(遵守访问权限),不能调用子类的特有成员,但最终的运行结果看运行类型的具体实现,能调用那些成员看编译类型,具体运行看运行类型。
5.多态的向下转型
语法:子类类型 引用名 = (子类类型) 父类引用;只能强转父类的引用,不能强转父类的对象。要求父类的引用必须指向的是当前目标类型的对象。可以调用子类类型中的所有成员。
public class Test { public static void main(String[] args) { //向上转型 A a = new B(); a.say(); //a.abc(); 方法abc为运行类型B类特有的编译类型A类不能调用 //调用那些成员看编译类型,具体运行看运行类型 //向下转型 B b = (B) a; //父类的引用必须指向的是当前目标类型的对象 b.abc(); }}class A { public void say (){ System.out.println("A类的say()被调用"); }}class B extends A { public void abc(){ System.out.println("B类的abc()被调用"); } public void say (){ System.out.println("B类的say()被调用"); }}
运行结果如下:
6.Java动态绑定机制
当调用对象的方法时,该方法会与该对象的内存地址/运行类型绑定。
当调用对象的属性时,不存在动态绑定机制。
public class Test { public static void main(String[] args) { A a = new B();//A为编译类型,B为运行类型 System.out.println(a.sum()); //B类中sum()没注释前 结果为 40 注释后结果为 30 //注释后会调用A类的sum方法但因为动态绑定机制sum中的getI方法调用的是B中的 System.out.println(a.sum1()); //B类中sum()没注释前 结果为 30 注释后结果为 20 //调用A类的sum1,i由于是调用对象的属性,不存在动态绑定机制,哪里声明就调用哪的i=10 }}public class A { public int i = 10; public int sum() { return getI() + 10; } public int sum1() { return i + 10; } public int getI() { return i; }}public class B extends A { public int i = 20;// public int sum() {// return i + 20;// } // public int sum1() {// return i + 10;// } public int getI() { return i; }}
7.多态数组多态参数
多态数组
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型和父类类型。
多态参数
方法定义的形参类型为父类类型,实际类型允许为子类类型。
示例:父类为Employee,子类为Worker和Manage
public class Test { public static void main(String[] args) { Test test = new Test(); Employee employee = new Employee("Bob",3000); Employee[] employee1 = new Employee[5];//多态数组 父类定义 Worker worker = new Worker("Tom",5000); Worker worker1 = new Worker("Kit",6000); Manager manager = new Manager("Smith",12000,100000); Manager manager1 = new Manager("Sab",15000,110000); employee1[0]=worker;//可放子类 employee1[1]=worker1; employee1[2]=manager; employee1[3]=manager1; employee1[4]=employee;//也可放本类 test.showEmpAnnal(worker);//多态参数 实参可为子类 test.showEmpAnnal(manager); test.testwork(employee1); } public void showEmpAnnal(Employee e){//多态参数 形参为父类 System.out.println(e.getName()+" 的年薪为:"+e.getAnnual()); } public void testwork(Employee e[]){ for (int i = 0; i <5 ; i++) { if(e[i] instanceof Worker){ ((Worker) e[i]).work();//向下转型 }else if(e[i] instanceof Manager){ ((Manager) e[i]).manage(); }else { System.out.println("员工 "+e[i].getName()+" 正在摸鱼!"); } } }}
到此这篇关于Java轻松掌握面向对象的三大特性封装与继承和多态的文章就介绍到这了,更多相关Java封装 继承 多态内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。