ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

面向对象编程的三大特性

2022-05-03 09:02:26  阅读:142  来源: 互联网

标签:Student 子类 特性 Person 面向对象编程 父类 public 三大 name


OOP三大特性

封装

程序设计追求高内聚,低耦合

  • 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
  • 低耦合:仅暴露少量的方法给外部使用。

封装(即为数据的隐藏)
通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。

进行封装的操作:将属性设为私有private,设立get/set方法

set方法里面还可以做一些安全性的验证和判断

快捷键alt+insert快速生成get/set方法

public class Student{
    //属性私有
    private String name;
    private int id;
    private char sex;
    
    //提供一些可以操作这个属性的方法,如提供public的get/set方法 
    
    //get 获得这个数据
    public String getName(){
        return this.name;
    }
    
    //set给这个数据设置值
    public void setName(String name){
        //要有形式参数 会被调用
        this.name = name;
    }
}
public class Demo{
    public static void main(String[] args){
       
        Student student = new Student();
           //属性私有的情况下, student.name;是错误的,不可以这样使用,会爆红
     String name =  student.getName();//这样就可以得到name了
      
        //通过set方法设置一个名字,这个值会传到setName()方法中,name就会被赋到值
        student.setName ("fafa");
        
        //输出name
         System.out.println(student.getName());
    }
}

使用封装可以规避一下不合法的输入,例如有一个int age

s1.setAge(999);//不合法的,又不是太上老君谁能活这么长
 public String getAge(){
        returnage;
    }
   
    public void setName(int age){
         if(age>120 || age<0){
         //不合法情况直接给他们赋一个正常的值,避免破坏程序
             this.age = 18;
         }
       else{
           this.age = age;
       }
    }

小插曲:方法中this.xx=xxx this. 代表当前类 ,而后面=的那个就是参数传进来的值

封装的意义

  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节
  3. 统一接口 都是get/set
  4. 系统的可维护性增加的,便于修改内部代码

继承

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

继承关系的俩个类,一个为子类(派生类),一个为父类(基类);一般成为父子关系。子类继承父类,使用关键字extends来表示。子类和父类之间,从意义上讲应该具有"is a"的关系,就如 旺财 is a dog

extends的意思是“扩展” 其中子类是父类的扩展。

子类继承了父类,就会拥有父类中的全部方法,前提是该方法修饰符是public,不过一般属性才是私有的

修饰符优先级 public protected default(默认的,不写修饰符时就默认是这个) private

JAVA中类只有单继承,没有多继承!一个儿子只能有一个爸爸,但一个爸爸可以有多个儿子。直接的继承只有一个,但间接的继承可以有多个

在Java中,所有的类都默认直接或间接继承object类

super

public class Application{
    public static void main(String[] args){
        Student student = new Student();
        student.test("花花")
    }
    
}
public class Person{
    protected String name = "fafa";
}
public class Student extends Person{
    private String name = "huahua";
    
    public void test(String name){
        //形参
         System.out.println(name);//当前这个string name 传递过来的参数 输出花花
         System.out.println(this.name);//指代当前Student类中的这个name 输出huahua
         System.out.println(super.name);//调用到父类中的name 输出fafa
    }
}

super同样适配继承方法的调用

public class Student extends Person{
    public void print(){
         System.out.println("student");
    }
    public void test1(){
        print();//调用当前类中的print方法,输出student
        this.print();//当前类中的print方法 输出student
        super.print();//调用了父类中的print方法 输出person
    }
}
public class Person{
    //注意是public修饰 私有的东西是无法被继承的!!
    public void print(){
         System.out.println("person");
    }

super中的构造器

public class Person{
    public Person(){
         System.out.println("Person的无参构造执行了");
    }
    }
public class Student extends Person{
    public Studenr(){
        //这里有一个隐藏代码 调用了父类的无参构造
        //即隐藏了 super();
        //而且调用父类的构造器,必须要在子类构造器的第一行,即这个super()一定要在这个sout上面
        //this同理,调用自己的构造器(有参)也要放第一个,所以调用构造器,要么调用父类 要么调用子类的
        //如果父类中没有无参构造,那么就必须写出来是super("...")
         System.out.println("Student的无参构造执行了");
    }
}
public class Application{
    public static void main(String[] args){
        Student student = new Student();
        //会执行
        //1 Person的无参构造执行了
        //2 Student的无参构造执行了
    }
    
}

super注意点

  1. super调用父类的构造方法,必须要出现在构造方法的第一个
  2. super必须只能出现在子类的方法或构造方法中
  3. super和this不能同时调用构造方法

super和this的区别

  • 代表的对象不同
    1. this: 谁调用它就是谁,代表本身调用者这个对象
    2. super: 代表父类对象的应用
  • 使用前提不同
    1. this:没有继承也可以使用
    2. super: 只能在继承条件下才可以使用
  • 调用构造方法不同
    1. this: 调用本类的构造
    2. super: 调用父类的构造

方法的重写

重写都是方法的重写,与属性无关

重写的关键词只能是public 不能是private

静态方法下(与重写无关)

public class A extends B{
      public static void test(){
         System.out.println("aaaaa");
    }
}
public class B{
    public static void test(){
         System.out.println("bbbbb");
    }
}
public class Application{
    public static void main(String[] args){
        A a =  new A();
        a.test();//输出aaaaa
    
        //在静态方法下 方法的调用只和左边有关即定义的数据类型有关
        //父类的引用指向子类
        B b = new A();
        b.test();//输出bbbbb
        
        
    }

非静态方法下

public class A extends B{
    @Override
      public void test(){
         System.out.println("aaaaa");
    }
}
public class B{
    publicc void test(){
         System.out.println("bbbbb");
    }
}
public class Application{
    public static void main(String[] args){
        A a =  new A();
        a.test();//输出aaaaa
    
        //重写只和非静态方法有关
        //父类的引用指向了子类
        B b = new A();//子类重写了父类的方法 就会执行子类的方法
        b.test();//输出aaaaa
        
        //子类跟父类都有的情况下,只要子类没有重写父类就调用父类的 子类要是重写了就调用子类的
    }

重写的小结

  1. 需要有继承关系,子类重写父类的方法
  2. 方法名必须相同
  3. 参数列表必须相同
  4. 修饰符:范围可以扩大,但不能缩小。 就像父类是public,子类想变成private是不可能的
  5. 抛出的异常:范围可以被缩小但不能扩大

重写,子类的方法和父类必须要一致,方法体不同

tips: 快捷键 alt+insert 选择override

多态

多态即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

多态存在的条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

注意:多态是方法的多态,属性没有多态性

//一个对象的实际类型是确定的
//new Student();
//new Person();

//but 可以指向这个对象的引用类型是不确定的
//即父类的引用指向子类
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();

//Student能调用的方法都是自己的或者继承父类的
//Person是父类型,虽然可以指向子类,但是不能调用子类独有的方法

对象能执行哪些方法,主要看对象左边的类型,和右边的关系不大

多态小结 (注意事项)

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类之间要有联系,不然会有类型转换异常(ClassCastExcepetion),就像String类型不能转为Person类型,狗不能转换为猫
  3. 多态存在的必要条件:
    • 继承关系
    • 方法需要重写
    • 父类引用指向子类对象 father f1 = new Son();

but !有些方法不能被重写

  • static方法,静态方法是属于类的,不属于实例
  • final是常量的,被final修饰的在常量池中也不能被重写
  • private方法是私有的,也不能被重写

instanceof

instanceof关键字判断两个类之间是否存在父子关系

instanceof关键字是在比较对象是否为后面类的实例

Object object = new Student();
//Object > Person > Student
//Object > Person > Teacher
//Object > String

//只有在同一个线上才能比出true
//非同一线上比较会编译错误

 System.out.println(object instanceof Student);//True
 System.out.println(object instanceof Person);//T
 System.out.println(object instanceof Object);//T
 System.out.println(object instanceof Teacher);//False
 System.out.println(object instanceof String);//F

类型转换

高转低要强制转换

//例如Person类中有run方法 , Student类中有go方法
//父类转子类

//高                低
Person pp = new Student();
//pp.go();这是错误的 需要强制转换

//pp目前是Person类型的 需要将pp这个对象转换为Student类型,这样就可以使用Student类型的方法了

Student student = (Student)pp;
student.go();

//如果整合就是 ((Student)pp).go();

低转高不需要操作

//子类转换为父类,可能会丢失自己本来的一些方法
//低转高是自然发生的 student转person直接写就可以了
Person person = student;
//但这时要用go方法 不可以person.go() 需要强制转换成
((Student)pp).go();

多态小结

  1. 父类引用指向子类的对象
  2. 把子类转换为父类,向上转型,不需强制转型
  3. 父类转换为子类,向下转型,需强制转换
  4. 方便方法的调用,减少重复的代码

标签:Student,子类,特性,Person,面向对象编程,父类,public,三大,name
来源: https://www.cnblogs.com/aowei/p/16217636.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有