• JAVA笔记整理-面对对象-特征


    一、Java的面向对象的特征

    1、封装(隐藏)

    对类中的成员属性进行隐藏(私有化),对类中的成员方法公共。

    2、继承

    ​ 一个类A可以继承另一个类B,这里类A就是类B的子类,类A可以继承类比的属性和方法,也可以定义自己的属性和方法

    3、多态

    ​ 为了适应需求的多种变化,类可以呈现多种形态,是代码更加通用

    1、封装

    为了提高类的隐蔽性,对类实现的细节隐藏,提供外部访问的接口即可,提高代码的可扩展性

    生活中的封装: 例如笔记本 的内部结构统一封装了,一般人使用笔记本时不需要了解笔记本的结构,而是直接开机关机使用。

    对代码的封装包括两层意思:

    1、对类的成员属性的封装 :

    ​ 将属性私有化(private),提供对属性的访问给属性添加公用的getter和setter方法

    2、对代码的封装:

    ​ 为了提高代码的复用性,尽量使用方法加参数传递对代码进行封装,并使该方法公有(public)

    public class People {
        private String pname;
        private int age;
        private String sex;
        // 提供 getter 和 setter 
        public String getPname(){    //获取gteter
            return pname;   
        }
        public void setPname(String pname){  //设置setter
            this.pname=pname;
        }
    
        public int getAge(){
            return age;
        }
        public void setAge(int age){
            // 对成员属性的隐蔽性 可以防止随意对属性更改
            if(age>100 || age<0){
                System.out.println("赋值的年龄不合法");
                return;
            }
            this.age = age;
        }
        public String getSex(){
            return sex;
        }
        public void setSex(String sex){
            this.sex= sex;
        }
        // 通常为了方便给属性赋值,会提供有参构造
        public People(String pname ,int age,String sex){
            this.pname = pname;
            this.age = age;
            this.sex = sex;
        }
        //无参构造
        public People(){
        }
     }
    

    ​ 对于boolean类型的属性,需要使用 is Xxx 返回属性的值。

    封装的优点:

    ​ 1、良好的封装可以减少类的耦合性(类与类的关联)

    ​ 2、对类中封装的代码可以自由修改,而不会影响其他类

    ​ 3、最大程度提高类中属性的隐蔽性 和对属性的控制

    2、访问修饰符的权限

    ​ 用于修饰类,属性,方法的关键字都称为访问修饰符

    1. 1、public :公共的

    ​ 可被同一个项目的所有类方法(项目可见性)

    1. 2、protected :受保护

    ​ 可以被自身的类访问

    ​ 可以被同包下的其他类访问

    ​ 对于不同包的,存在父子关系的子类可以访问

    1. 3、默认的

    ​ 可以被自身类访问

    ​ 可以被同包下的其他类访问

    1. 4、private: 私有的

    ​ 只能被自身类访问

    访问修饰符 同一个类 同一包不同类(子类或非子类) 不同包的子类 不同包
    public
    protected ×
    默认 × ×
    private × × ×

    3、static关键字

    ​ static表示“静态” ,它可以修饰 属性,方法,代码块 , 在一个类中除了可以定义成员属性、成员方法和构造器以外,还可以定义静态的部分(静态属性,静态方法,静态代码块)

    static 修饰属性:称为 静态属性或类的属性

    static修饰方法:称为静态方法或类的方法

    static修饰的语句块: 称为静态代码块

    static修饰的组件不需要通过对象访问,而是直接通过类名访问,在类一加载时会给static修饰的属性和方法分配内存区,这个内存分布在 静态内存区中。后续所有对象操作的是同一个内存区

    案例一:

    public class Student {
        //  成员属性
        String name;
        // 静态属性  通常static写在public的后面
        static  int age=20;
    
        // 静态代码块
        static{
            System.out.println("这是静态代码块,在类一加载时,就会被执行,且只执行一次");
        }
    
        //成员方法  : 既可以访问 成员属性,也可以访问静态属性
        public void getInfo(){
            System.out.println("姓名:"+name +" 年龄:" +age);
        }
        // 静态方法 : 只能访问静态属性,不能访问成员属性(非静态属性
        //   这是为什么? 由于成员属性的存在需要依赖对象 ,
        // 静态属性和静态方法在创建对象之前就必须初始化并分配内存
        public static void getStaticInfo(){
           // System.out.println("姓名:"+name);  成员属性不能被访问
            System.out.println("静态属性:"+age);
        }
        public Student(){
            System.out.println("无参构造器");
        }
        // 构造代码块
        {
            System.out.println("构造代码块");
        }
        public static void main(String[] args) {
            System.out.println("访问静态属性:"+Student.age);
            // 访问静态方法
            Student.getStaticInfo();
        }
    
           // 类的组件执行顺序
            // 类编译成.class文件被JVM的类加载器加载-》
            // 从上往下初始化static修饰的组件
            // (静态属性,静态代码块,静态方法,其中静态方法调用才执行,静态属性和静态代码块直接分配内存)-》
            //  --》构造代码块-》执行构造器  -》初始化成员属性,成员方法
            Student stu1 = new Student();
            stu1.name="张三";
            // 静态属性可以通过类名访问,也可以通过对象名访问
            stu1.age=21;
            System.out.println(stu1);
    
            Student stu2 = new Student();
            stu2.name="王麻子";
            stu2.age=22;
            System.out.println(stu2);
    
            System.out.println(stu1.name);
            System.out.println(stu1.age); //   22
    
            System.out.println(stu2.name); //王麻子
            System.out.println(stu2.age); // 22
    
            System.out.println(Student.age);//  22
    
        }
    

    案例二: 静态的变量 在同一个内存中

    public class People {
        double height;
        static int score;
        static{
           score++; // 1
        }
       public void setScore(){
           score++; //81  86
       }
       public static void setScore2(){
            score++;
       }
    
        public static void main(String[] args) {
             People p1 = new People();
             p1.score=80;//静态属性
             p1.setScore();
             People.score=85;
             p1.height= 1.75;
             People p2 = new People();
             p2.setScore(); //86
             p2.height= 1.80;
    
            System.out.println(p1.score); // 86
            System.out.println(p1.height); // 1.75
    
            System.out.println(p2.score);//86
            System.out.println(p2.height);// 1.80
    
        }
    
    }
    

    案例三: 构造代码块和静态代码块 的执行顺序

    package com.j2008.statics;
    
    /**
     * ClassName: UserInfo
     * Description:
     * date: 2020/10/8 11:53
     *
     * @author wuyafeng
     * @version 1.0   softeem.com
     */
    public class UserInfo {
        //  关于静态的组件 从上往下执行
        // 静态属性  需要先初始化 ,需要new一个对象
        static UserInfo u = new UserInfo(); // 先执行构造代码块 在执行构造器
        static{
            System.out.println("这是静态代码块,只执行一次");
        }
    
        public UserInfo(){
            System.out.println("这是无参构造器");
        }
        {
            System.out.println("构造代码块");
        }
    
        public static void main(String[] args) {
             // 结果
            UserInfo u = new UserInfo();
        }
    
    
    }
    
    

    结果:

    构造代码块
    这是无参构造器
    这是静态代码块,只执行一次
    构造代码块
    这是无参构造器

    4、继承

    4.1、概念

    当多个类中都存在相同的属性和行为时,可以将这些共有的属性和行为定义到一个新的类中,让其他类服用这个新类的属性和行为,这种关系就是继承关系

    当满足 XXX是 一个XXX的时候,也是继承关系,例如 苹果是一种水果,其中水果就是父类,苹果就是子类, 水果有多种水果,而苹果只是水果的一种,所以苹果继承水果

    其中 被继承的类是 父类(超类,基类),继承父类的类就是子类(新类,派生类)

    4.2、继承的语法

    ​ 先定义父类

    public  class 父类{
        
    }
    

    再定义子类

    public class 子类 extends 父类{
        
    }
    

    2.1 子类继承父类,子类拥有父类的哪些属性和方法?

    可访问: 子类拥有父类的共有的属性和方法, 同包下面的属性和方法,不同包下 受保护的属性和方法也可以访问

    不可访问: 其中子类不能继承父类的私有的属性和方法、不同包的默认属性和方法 ,不能继承父类的构造器

    2.2 子类继承父类,子类如何访问父类的属性和方法

    属性: 子类通过super 关键字访问父类的属性 ,子类通过this关键字访问自己的属性

    方法:子类通过super挂件自方法父类的方法, 子类通过this关键字访问自己的方法

    注意: 这里的this和super可以省略,省略后子类通过“就近原则”访问属性和方法(子类中存在就访问子类的,子类中不存在,就访问父类的。)

    super.属性

    super.方法(参数)

    构造器:子类通过super([参数]) 调用父类的构造器, 子类通过this([参数])调用 自己类的其他构造器,其中 super(参数[]) 必须写在子类构造器的第一行

    通过在子类构造器手动调用父类的有参构造器给父类的属性赋值

    public class Employee {
        String ename="王麻子";//员工姓名
        double sal=5000 ; // 员工薪资
        
         public Employee(String ename,double sal){
            this.ename = ename;
            this.sal = sal;
        }
     }
    
    public class Manager extends Employee{
        // 奖金
        private double comm;
         public Manager(String ename ,double sal ,double comm){
            // 如何覆盖父类的无参构造器 ,手动调用父类的有参构造
            super(ename ,sal);  // 只能写在第一句
            this.comm = comm;
        }
      }
    

    注意: 子类构造器中默认调用父类的无参构造器

    2.3 Java中只能是单继承,一个类只能有一个直接父类的父类,可实现多层次继承

    ​ 子类 -》 父类 -》 父类的父类

    ​ pupil -> Student-》 People

    创建子类对象时,优先创建父类对象,再创子类对象, 执行顺序 最上层父类的构造器 -》 父类构造器 -》子类构造器。

    扩展问题:当一个类中存在static元素时,它们的执行顺序是如何?

    顺序: 最上层父类的静态块 - 》 父类的静态块-》 子类的静态块- 》最上层 父类的构造块和构造方法

    -》父类的构造块和构造方法- 》 子类的构造块和构造方法

    public class People {
        static{
            System.out.println("People的静态语句块");
        }
        public People(){
            System.out.println("People类的无参构造器");
        }
        {
            System.out.println("People的构造语句块");
        }
    }
    
    public class Student extends  People{
        static{
            System.out.println("Student 的静态语句块");
        }
        public Student(){
            // 默认调用父类的构造器
            System.out.println("Student的无参构造器");
        }
        {
            System.out.println("Student的构造语句块");
        }
    }
    public class Pupil extends  Student {
        static{
            System.out.println("Pupil的静态语句块");
        }
        public Pupil(){
            // 调用它父类的无参构造器
            System.out.println("Pupil类的无参构造器");
        }
        {
            System.out.println("pupil的构造器语句块");
        }
    }
    
    
      public static void main(String[] args) {
              //创建Pupil对象
            Pupil pupil = new Pupil();
    
        }
    

    结果:

    People的静态语句块
    Student 的静态语句块
    Pupil的静态语句块
    People的构造语句块
    People类的无参构造器
    Student的构造语句块
    Student的无参构造器
    pupil的构造器语句块
    Pupil类的无参构造器

    4.3、重写

    子类可以继承父类的方法,但是当父类的方法不能满足子类的需要时,子类可以重写父类的方法

    重写的必要条件:

    1、两个方法名必须相同,且存在不同类中(父子关系的类)

    2、子类重写的父类的方法,其方法的参数和返回值必须完全一样,方法的具体实现可不一样

    3、访问修饰符必须大于或等于父类的修饰符

    注意: 子类的对象 调用父类方法时,如果子类重写了父类的方法,则执行子类的方法,没有重写执行父类的方法。

    面试题:

    说一下方法的重写与重载的区别?

    1、重写存在于父子关系中的不同类,重载存在同一个类中

    2、重写必须满足 方法名相同,且参数相同,返回值相同 ,重载满足方法名相同,参数不同,与返回值无关。

    3、重写的访问修饰符必须 子类大于等于父类, 重载没有要求

  • 相关阅读:
    计算机为什么要从 0 开始计数?
    MySQL索引结构为什么是B+树
    expdp导出报错ORA-39127
    expdp 跳过坏块
    (转)没有索引导致的DIRECT PATH READ
    Python的实用场景有哪些
    Oracle索引修复 ,ORA-00600: internal error code, arguments: [6200],
    CentOS7.6静默安装19C实例脚本 ORA-27125 [FATAL] [DBT-10322]
    ORA-00313: 无法打开日志组
    cursor: pin S wait on X等待事件的处理过程(转载)
  • 原文地址:https://www.cnblogs.com/z5452830/p/13798453.html
Copyright © 2020-2023  润新知