首页 > 其他 > 详细

面向对象OOP

时间:2021-02-15 10:07:19      阅读:33      评论:0      收藏:0      [点我收藏+]

面向对象OOP

面向对象可以有利于对系统的宏观把控,将系统按各自的特点分割成不同的类别、子类,然后再以面向过程的思想进行微观实现。

面向对象编程

本质:以类的方式组织代码,以对象的方式封装数据

抽象

三大特性

  • 封装
  • 继承
  • 多态

代码的角度是先有类,后有对象,类是对象的模板;生活中则是先有对象,再抽象出类。

类的组成

  • 属性
  • 方法

对象的创建

  • new,本质是调用构造器,分配内存空间

  • 构造器,初始化对象

    • 构造器和类名必须相同
    • 构造器没有返回类型,也不能写void
    • 定义有参构造后(即重载)必须显示定义无参构造
    public class Person {
        
        public Person(){
            System.out.println("无参构造器");
        }
        
        public Person(String name){
            System.out.println("有参构造器"+name);
        }
    }
    

封装

程序设计

  • 高内聚:数据的操作在类的内部完成,不让外部知道和干涉

  • 低耦合:仅暴露少量的接口供外部使用

  • 属性私有,get/set

    public class Person {
        int age;
        String name;
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            if (age>=0||age<120){
                this.age = age;
            }else{
                System.out.println("年龄不合法!");
            }
            
        }
        
    }
    

作用

  1. 提高程序安全性,保护数据
  2. 隐藏代码实现细节
  3. 统一接口
  4. 提高系统可维护性

继承

  • 本质是对某一批类的抽象
  • 使用extands关键字,子类(派生类)是父类(基类)的扩展
  • Java只有单继承,没有多继承
  • 所有类都直接或间接继承自object类
  • 私有的属性或方法无法被继承
  • 类和类之间的关系除了继承,还有组合、依赖、聚合等

四种修饰符的区别

  1. public:权限最高,可跨包访问
  2. protected:权限次之,可在同包、本类和子类中访问
  3. default:默认,一般不写,可在同包中访问
  4. private:权限最低,私有,只能在本类访问
外包 本包 子父类 本类
public
protected ×
default × ×
private × × ×
  • protected注意访问的方式

    public class Son extends Person {
    public static void main(String[] args) {

        //错误的访问父类的protected方法
        //Person person = new Person();
        //person.setAge();
        
        //正确打开方式,通过创建子类对象来访问
        Son son = new Son();
        son.setAge(10);
    }
    

    }

?

super和this

区别

  1. 代表的对象不同,super代表父类对象的引用,this代表调用者对象本身
  2. 前提不同,super只能在继承条件才可使用,this没有继承也可使用
  3. super()代表父类的构造方法,this()代表本类的构造方法

super注意点:

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

构造器调用

new子类对象时,默认会调用父类以及祖父类...的无参构造器
技术分享图片

package com.kuang.oop.Demo01;

public class Student extends Person{
	//子类无参构造器
    public Student() {
        super();//调用父类构造器必须放在子类构造体第一行
        System.out.println("子类无参执行");
    }
    //子类有参构造器
    public Student(String name){
        super(name);//可以显示调用父类有参构造,否则依然默认调用父类的无参构造
        this.name=name;
        System.out.println("子类有参");
    }
  • 调用子类有参构造器来new子类对象,默认调用的依然是父类的无参构造器,除非在子类有参构造器方法体第一行显式调用父类的有参构造

重写

作用

根据需要,通过重写来对父类的方法进行扩展增强

要点

  1. 子类的方法必须与父类相同(包括方法名、参数列表和返回值类型
  2. 重写的方法可以使用@Override注解来标识
  3. 权限修饰符:范围可以扩大但不能缩小-----public>protected>default>private
  4. 方法抛出异常:范围可以缩小但不能扩大

多态

条件

  1. 有继承关系
  2. 子类重写父类(祖父类)的方法
  3. 父类(祖父类)的引用指向子类的对象

作用

方便方法的调用

强制转换

  • 父类(祖父类)引用指向子类对象,父类(祖父类)可调用子类独有的方法,但必须先进行强制类型转换(高转低,范围大的是高如:double>int ,Father>Son)

    Father f = new Son();//称f为子类Son的上转型对象
    /*
    拆分出来可以看成是这样:
    Son s = new Son();
    Father f = s;
    子类引用类型(低)转父类引用(高),向上转型不用强转,但会丢失子类独有的方法,即使是同名的属性或重写的方法,调用时也是调用父类的。并且无法调用父类私有的属性和方法,如被static、final、private修饰的属性和方法。
    **/
    
    ((Son)f).sonEat();//想要调用子类独有的方法,必须将引用类型进行强转,向下转型
    
    
  • 实例对象可调用的方法由引用类型决定

  • 只有直接或间接继承,并且父类引用指向子类对象时,才能对父类引用进行强转

基本数据类型的转换

低-------------------------------------->高
byte-->short-->int-->long-->float-->double//能转换的前提是高数据类型范围完全包含低数据类型范围,如byte和char就不能相互转
char-->int-->long-->float-->double
    
运算中,不同数据类型要先进行数据类型转换,然后再计算

强制类型转换

  1. 高转低(高容量转低容量)

  2. 可能导致溢出

  3. 可能导致精度丢失

  4. (类型)变量名

    int i = 128;
    byte b = (byte)i;//输出结果b变成-128,因为强转后溢出
    
    double d = 1.8;
    int i2 = (int)d;//输出结果i2为1,截断,丢失精度
    

自动类型转换

  1. 低转高

  2. 自动转换

    int i = 1;
    double d = i;//不用强制转换,输出结果d为1.0
    

注意

  1. 多态是指方法的多态,属性没有多态

  2. 被static、final和private修饰的方法不能重写

  3. 真正的父类对象不能强转成子类对象;但真正的子类对象可以,实际是自动转换的。

    Father f = new Father();
    Son s = (Son)f;//报错,实际就是Son s = new Father()的写法是错误的
    
    Son s = new Son();
    Father f = (Father)s;//(Father)可不写,等价于Father f = new Son();
    
  4. 子类的上转型对象重新强制转换回子类对象时,子类原有的私有属性和方法依然是不可使用

    public class Student extends Person{
    
        private  int age=5;
        private void study(){
            System.out.println("study");
        }
    }
    ========================================
    public class Application  {
        public static void main(String[] args) {
    
            Person s = new  Student();
            int age = ((Student)s).age;//报错,私有属性不可访问
            ((Student)s).study();//报错,私有方法不可访问
        }
    }
    /*
    通俗理解:
    儿子想装爸爸---------上转型Person s = new  Student();
    被打回原型----------强制转换Student s =(Student)s;
    儿子死鸭子嘴硬坚决不承认,不能暴露自己是儿子的特征--------不能使用原来私有的方法和属性
    **/
    

instanceof

  • 用来判断new出来的实例对象是否属于某个类
  • 对引用类型数据进行判断
  1. 能否进行判断,先决条件是引用类型跟参与判断的类是否具有父子关系,若无,则编译直接报错

    //Object>Person>Student
    //Object>Person>Teacher
    Student s = new Student();
    
    System.out.println(s instanceof String);//s与String没有父子关系,编译报错
    System.out.println(s instanceof Teacher);//同上,报错
    
  2. 判断结果由对象类型是否属于参与判断的类决定

    Student s = new Student();
    Person  p = new Student();
    
    System.out.println(s instanceof Person);//True
    System.out.println(s instanceof Object);//True
    System.out.println(p instanceof Student);//False
    System.out.println(s instanceof Teacher);//False
    
  3. 结果为True的时候,才可以进行强制转换,否则转换报错:ClassCastException

    Person p = new Student();
    
    System.out.println(p instanceof Student);//True
    ((Student)p).study();//强转成功并调用Student的方法
          
    System.out.println(p instanceof Teacher);//False
    ((Teacher)p).teach();//强转失败,运行报错Exception in thread "main" java.lang.ClassCastException: com.kuang.oop.Demo01.Student cannot be cast to com.kuang.oop.Demo01.Teacher
    

Static关键字

  • static修饰的属性被所有实例共享

//java改变Static修饰的属性,会影响类变量和其他实例变量的值
public class Application  {
    public static void main(String[] args) {

        Person p1 = new Person();
        System.out.println(p1.age);//10
        p1.age=11;
        Person p2 = new Person();
        System.out.println(p2.age);//11
		System.out.println(Person.age);//11
    }
}
  • 类加载过程和static详解

    1. 静态方法可以被继承,但不能被重写;private方法和属性也可以被继承,但子类不能直接进行访问和重写

    2. java使用static来实现全局变量的概念,所有实例共享静态变量,任何实例对静态变量的改动,都会反馈到其他实例上

    3. 静态变量和静态方法可以直接通过类名进行访问,随着类的加载同时加载和分配内存空间

    4. 没有static修饰的变量为成员变量,随着对象的创建而产生,随着对象的消失而消失

    5. 静态方法的存在与对象无关,因此不能通过this或super的方式进行调用

    6. 静态方法只能访问其他静态方法或静态变量,非静态方法则无此限制

    7. 静态代码块、匿名代码块和构造器的加载过程:

      main()程序入口-->父类的static代码块-->子类的static代码块-->父类的匿名代码块和构造器-->子类的匿名代码块和构造器
      
    8. Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字

    9. 在Java中切记:static是不允许用来修饰局部变量

    10. static块可以出现类中的任何地方(只要不是方法内部,记住,任何方法内部都不行),并且执行是按照static块的顺序执行的

    11. 子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过

面向对象OOP

原文:https://www.cnblogs.com/zuozs/p/14402551.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!