JAVA面向对象03---封装,继承,方法重写,多态
2022/4/14 9:13:12
本文主要是介绍JAVA面向对象03---封装,继承,方法重写,多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
JAVA面向对象03
封装
- 改露的露,改藏的藏
- 我们的程序设计要追求”高内聚,低耦合“。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量方法给外部使用
- 封装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这成为信息隐藏
- 属性私有,get/set
//类 private: 私有 /* 1.提高程序的安全性,保护数据 2.隐藏代码的实现细节 3.统一接口 4.系统的可维护性增加了 */ public class Student { //属性私有 private String name;//名字 private int id;//学号 private char sex;//性别 private int age;//年龄 //提供一些可以操作这个属性的方法 //提供一些public的 get set的方法 //get 获得这个数据 public String getName(){ return this.name; } //set给这个数据设置值 public void setName(String name){ this.name = name; } //alt + insert public int getId() { return id; } public void setId(int id) { this.id = id; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { if(age>120||age<0){//不合法 this.age = 3; }else{ this.age = age; } } /* public static void main(String[] args) { Student s1 = new Student(); String name = s1.getName(); s1.setName("zhiyuan"); System.out.println(s1.getName()); s1.setAge(999);//不合法 */ }
继承
- 继承的本质是对某一批类的抽象,从和实现对现实世界更好的建模
- extends的意思是”扩展“。子类是父类的扩展
- java中类只有单继承,没有多继承,一个儿子只有一个爸爸,一个爸爸可以有多个儿子
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合,聚合等
- 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
- 子类和父类之间,从意义上讲应该具有“is a”的关系
- object
- super
- 方法重写
子类可以可以通过继承获取父类原有的字段和方法,也可以在父类的基础进行扩展,使用extends来表示子类和父类之间的继承关系,类之间只支持单继承,一个类只能有一个直接父类,可以多重继承
//在JAVA中,所有的类都默认直接或间接继承object //Person 人:父亲 public class Person /*extends object*/{ //public //protected //default //private private int money = 10_0000_0000; public void say(){ System.out.println("说了一句话"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } }
//Teacher is 人:子类,派生类 public class Teacher extends Person{ }
//学生 is 人:子类,派生类 //子类继承了父类,就会有父类的全部方法 public class Student extends Person{ //ctrl+h可以查看继承图 }
super
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
对比this
-
代表的对象不同
-
this:本身调用的这个对象
-
super:代表父类对象的应用
-
-
前提
- this:没有继承也能使用
- super:只能在继承条件下使用
-
构造方法
- this();本类的构造
- super();父类的构造
public class Student extends Person{ public Student(){ //隐藏代码:调用了父类父类无参构造 //super();调用父类的构造器,必须要在子类构造器的第一行 System.out.println("Student无参执行了"); } private String name = "xu"; public void print(){ System.out.println("xuzhiyuan"); } public void test1(){ print(); this.print(); super.print(); } public void test(String name){ System.out.println(name); System.out.println(this.name); System.out.println(super.name); } }
方法重写
-
需要有继承关系,子类重写父类的方法
-
参数列表必须相同
-
修饰符:范围可以扩大 但不能缩小:Public>Protected>Default>Private
-
抛出的异常:范围可以被缩小但不能扩大;
-
重写,子类的方法和父类必须要一致,方法体不同
为什么需要重写
-
父类的功能,子类不一定需要,或者不一定满足
-
重写快捷键:Alt+Insert;override;
public class A extends B{ //Override 重写 @Override//注解:有功能的注释 public void test() { System.out.println("A=>test()"); } }
//重写是方法的重写,和属性无关 public class B { public void test( ){ System.out.println("B=>test()"); } }
public class Application { //静态方法和非静态的方法区别很大 //静态方法:方法的调用只和左边的定义数据有关 //非静态:重写之和非静态有关 //重写和public有关,子类要重写父类方法 , //父类方法不一定必须要public 只要子类重写方法的权限修饰符不必父类更严格就行 public static void main(String[] args) { A a = new A(); a.test(); //父类的引用指向了子类 B b = new A();//子类重写了父类的方法 b.test(); //静态方法时 //用B类新建了A类的对象,把A赋值给了B, //这时候B是A,A又继承了B类,向上转型。 //所以调用B类方法的时候,也就是B=>test //非静态方法时 //即b是A new出来的对象,因此调用了A的方法 //因为静态方法是类的方法,而非静态是对象的方法 //有static时,b调用了B类的方法,因为b是用b类定义的 //没有static时,b调用的是对象的方法,而b是用A类new的 //可参考这句话理解:static修饰的方法归类所有,叫类的成员,不叫对象的成员 } } //重载是同一类里,方法名相同,参数类型不同。 // 重写是子父类间,子类重写父类的方法, // alt+insert,方法名相同,方法内容不同。 // 使用public方式,且不使用static方式
多态
- 动态编译
- 即同意方法可以根据发送对象的不通过而采取多种不同的行为方式
- 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类,有关系的类)
- 多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
- 多态是方法的多态,属性没有多态
public class Person { public void run() { System.out.println("run"); } /* 多态注意事项 1.多态是方法的多态,属性没有多态 2.父类和子类的联系 3.存在条件:继承关系,方法需要被重写,父类的引用指向子类对象 如:father f1 = new son(); 例外 1,static静态方法,属于类,不属于实例 2,final修饰的属于常量池里 3,private方法没法被重写,也没法实现多态 */
public class Student extends Person{ @Override public void run() { System.out.println("son"); } public void eat(){ System.out.println("eat"); } }
public class Application { public static void main(String[] args) { //一个对象的实际类型是确定的 //new Student(); //new Person(); //可以指向的引用类型就不确定了:父类的引用指向子类 //1. 使用父类类型的引用指向之类的对象 //2. 该引用只能调用父类中定义的方法和变量(非静态 //3. 如果子类中重写了父类中的一个方法,那么调用这个方法的时候,将会调用子类中的方法; //左边子类Student 能调用的方法都是自己或者继承父类的 Student s1 = new Student(); //左边父类Person,可以指向子类但是不能调用子类独有的方法 Person s2 = new Student(); Object s3 = new Student(); s2.run();//子类没有重写父类,就会调用父类方法, s1.run();//子类重写了父类的方法,就会执行子类的方法 ((Student)s2).eat();//强制转换可以实现子类调用自己的方法 //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大 } }
instanceof 类型转换
- 判断一个对象是否是有继承关系以及本身
public static void main(String[] args) { //Object > Person > Student //Object > String //Object > Person > Teacher Object object = new Student(); //System.out.println(X instanceof Y); //能不能编译通过,取决于X的引用类型和Y有没有父子关系,无则无法编译 System.out.println(object instanceof Student);//true System.out.println(object instanceof Person);//ture System.out.println(object instanceof Object);//true System.out.println(object instanceof Teacher);//false System.out.println(object instanceof String);//false System.out.println("=============================="); Person person = new Student(); System.out.println(person instanceof Student);//true System.out.println(person instanceof Person);//ture System.out.println(person instanceof Object);//true System.out.println(person instanceof Teacher);//false //System.out.println(person instanceof String);//无法编译 System.out.println("==========================="); Student student = new Student(); System.out.println(student instanceof Student);//true System.out.println(student instanceof Person);//ture System.out.println(student instanceof Object);//true //System.out.println(student instanceof Teacher);//无法编译 //System.out.println(student instanceof String);//无法编译 //只要是在引用(比如这里的Object)和实例化对象类型(比如这里的Student)之间的任何一个引用, //都是有联系的。而不在这条线上的,都是无关的 //看=的编译是否通过看=左边的类型,实际判断对象变为=右边的类型。 }
子类父类转换
public static void main(String[] args) { //类型之间的转化:父 子 //子类转换为父类,可能会丢失自己的本来一些方法 //低(子)转高(父)时,由于子已经继承了父的所有,所以删去属于自己的后自然而然就可以转化问父类的; //而父想要转子,则需要重新开辟只属于子的空间,则需用强制转换 //高 低 Person per = new Student(); Student per1 = (Student) per; per1.go(); per1.run(); per.run(); ((Student)per).go(); System.out.println("======================="); Student s1 = new Student(); Person p1 = s1; p1.run(); //p1.go();报错 子转父后,无法再调用自身的独有go方法 Person p2 = new Student(); Student s2= (Student) p2; s2.run(); //简写则可以这样,省略其中的过程 //这里把per对象看作一个人 编译的时候去Person找go方法 运行的时候去执行Stduent的go方法 //但父类Person并没有go方法,必须要转化引用类型 //将这个per对象转换为Student引用类型的per1对象,就可以使用Student类型的方法了 //子类转换为父类对象时,并没有实际丢失它原有内存空间(比父类多的那些部分) //只是暂时不可访问,所以能再强制转回来 } /* 1,父类引用指向(=)子类的对象,相反不行 2.把子类转换为父类,向上转型可以直接转换过去(会丢失子类独有的方法), 相反的向下转型的话,需要强制转换才行 3.方便方法的调用,减少重复的代码,简洁 抽象: 封装,继承,多态 */
这篇关于JAVA面向对象03---封装,继承,方法重写,多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略