java类学习

类与对象

  • 类是抽象的数据类型,对某一类事务的整体描述/定义,但是并不能代表某一个具体的事物
  • 对象是抽象概念的具体实例

面向对象编程

  • 三大特性
    • 封装
    • 继承
    • 多态
  • 面向对象编程:以类的方式组织代码,以对象组织数据
  • 使用new关键字创建对象
    • 分配内存空间
    • 进行默认的初始化,对类中的构造器进行调用
    • 本质调用构造方法
  • 构造器
    • 必须和类名相同
    • 必须没有返回类型,也不能写void
    • 无参构造是默认就有的,如果写构造函数就没了
    • 定义有参构造之后,如果想使用无参构造,必须显示的定义无参构造。
    • 使用alt+insert
  • 内存分析
    • 类生成的实例对象名(引用)放在栈中,真正生成对象各个赋值变量位于堆中
    • 堆: 存放new的数组和对象。栈: 存放基本变量类型和引用变量
    • 静态方法每个对象都可以调用
    • 方法区也属于堆
    • 在一个JVM实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中。类型信息是由类加载器在类加载时从类文件中提取出来的。类(静态)变量也存储在方法区中。

封装

  • 数据的隐藏,通常禁止访
  • 问一个对象的数据,通过操作接口来访问
  • 程序设计对求高内聚,低耦合,高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合仅暴露少量的方法给外部使用
  • 属性私有

继承

  • 关键字extends。子类是父类的扩展

  • java中类只有单继承,没有多继承

  • 派生类/子类;父类/基类

  • 继承是类和类之间的一种关系。初次之外还有依赖、组合、聚合等

  • ctrl+h 可以显示继承关系

  • 所有的类都直接或间接的继承Object类

  • 子类拥有父类非private的属性和方法

  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

  • 子类可以用自己的方式实现父类的方法。

  • 子类的构造函数默认的调用父类的无参构造函数,因此无参构造最好写,否则会报错,或者显示的调用父类的有参构造

  • super显示的调用父类的构造函数,必须放在第一行

  • super和this不能同时调用构造方法

  • Super

    • 通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

    • 无参构造,子类会默认调用父类的无参构造函数

    • 调用父类构造器必须放在子类构造器的第一行

    • 不可调用私有的

    • class Animal {
        void eat() {
          System.out.println("animal : eat");
        }
      }
       
      class Dog extends Animal {
        void eat() {
          System.out.println("dog : eat");
        }
        void eatTest() {
          this.eat();   // this 调用自己的方法
          super.eat();  // super 调用父类方法
        }
      }
       
      public class Test {
        public static void main(String[] args) {
          Animal a = new Animal();
          a.eat();
          Dog d = new Dog();
          d.eatTest();
        }
      }
      
  • final

    • 键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写

    • 声明类:

      final class 类名 {//类体}
      
    • 声明方法:

      修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
      
    • 实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。

  • 方法的重写

    • 声明为static的方法不能被重写
    • 不能重写私有
    • 参数列表必须相同
    • 修饰符:范围可以扩大 public>protected>default>private
    • 抛出的异常:抛出的范围,可以被缩小,但不能扩大;ClassNotFoundException-->Exception(大)
    • 意义
      • 父类的功能子类不一定需要或者不满足

向上转型和向下转型

  • 向上转型

    • 通过父类对象(大范围)实例化子类对象(小范围)(自动转换)

    • class A {
               public void print() {
                        System.out.println("A:print");
               }
      }
      
      class B extends A {
               public void print() {        
                        System.out.println("B:print");
               }
      }
      
      public class Test{
               public static void main(String args[])
               {
                        A a = new B();         
                        a.print();   //B:print
               }
      }
      
    • 打印的是class B的print,子类B去实例化A的,所以父类A的print方法已经被子类B的print方法覆盖了.

    • 当我们需要多个同父的对象调用某个方法时,通过向上转换后,则可以确定参数的统一.方便程序设计.

    • 向上转型时,父类只能调用父类方法或者子类覆写后的方法,而子类中的单独方法则是无法调用的.

  • 向下转型

    • 通过子类对象(小范围)实例化父类对象(大范围)

    • 向下转型则是通过父类强制转换为子类,从而来调用子类独有的方法(向下转型,在工程中很少用到).

    • class A {
               public void print() {
                        System.out.println("A:print");
               }
      }
      
      class B extends A {
               public void print() {        
                        System.out.println("B:print");
               }
               public void funcB(){
                        System.out.println("funcB");
               }
      }
      
      class C extends A {
               public void print() {        
                        System.out.println("C:print");
               }
               public void funcC(){
                        System.out.println("funcC");
               }
      }
      
      public class Test{
               public static void func(A a)
               {
                        a.print();
                        if(a instanceof B)
                        {
                                B b = (B)a;   //向下转型,通过父类实例化子类
                                b.funcB();    //调用B类独有的方法
                        }
                        else if(a instanceof C)
                        {
                                C c = (C)a;  //向下转型,通过父类实例化子类
                                c.funcC();   //调用C类独有的方法
                        }
               }
      
               public static void main(String args[])
               {
                        func(new A());   
                        func(new B());
                        func(new C());
               }
      }
      

多态

  • 动态编译:类型可扩张性变强
  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
  • 多态存在的条件
    • 有继承关系
    • 子类重写父类的方法
    • 父类引用之类的对象
  • 多态是方法的多态,属性没有多态性
  • 对象能执行那些方法都看左边的类型(等号左边)
  • 类型转换异常 ClassCastException
  • 对于static、private、final都哦不能多态
  • instanceof:这是在判断某个对象是否为某个类或其任意基类的实例

static

  • 静态变量对于类,所有对象(实例)所共享,当直接使用类去调用得到说明这个变量是静态的

  • 可以写静态代码块,只执行一次

  • 静态代码块最先执行,然后执行匿名代码块,再执行构造函数

  • 可以使用匿名代码块来赋值

    //赋初始值
    {
    	System.out.println("匿名代码块");
    }
    //只执行一次
    static{
    	System.out.println("静态代码块");
    }
    
    public class Student {
        private String name;
        {
            name="zhou";
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    '}';
        }
        public static void main(String[] args) {
            Student student=new Student();
            System.out.println(student);
        }
    
    }
    out:Student{name='zhou'}
    
  • 可以使用静态导入包里面的东西

import static  java.lang.Math.PI

抽象类

  • abstract修饰符可以修饰方法也可以修饰类
  • 抽象类可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
  • 抽象类不能使用new关键字创建,是让子类继承的
  • 抽象方法,只有方法的声明,没有方法的实现,他是用来让子类实现的
  • 子类继承抽象类,必须实现抽象方法,否则子类也要声明为抽象类
  • 类 extends只能值单继承,接口可以实现多继承(插座)
  • 由于单继承的局限性用的不是很多
  • 抽象类可以实现普通方法
  • 抽象类的意义
    • 提升开发效率,因为抽象类里面可以写一些公共的方法,这些可以达到复用

接口

  • 普通类只有具体的实现
  • 抽象类:具体实现+规范
  • 接口:只有规范,定义的是一组规则
  • 可以多继承
  • 关键词是implements
  • 接口定义的变量都是常量 public static final,一般不用
  • 所有的方法都是抽象方法public abstract
  • 抽象能力很重要,把系统的结构抽象成接口
  • 接口不能被实例化
  • 必须重写接口的方法

内部类

  • 内部类

  • 局部内部类

  • 一个Java文件可以有多个class类,但只能有多个public class

  • 没有名字初始化类,不用将实例保存

  • 匿名内部类

  • package com.zhou;
    
    public class Outer {
        private int id;
    
        public void out() {
            System.out.println("外部类方法");
        }
    
    
        public class Inner {
            public void in() {
                System.out.println("内部类类方法");
            }
    
            public void getid() {
                System.out.println(id);
            }
        }
    
        public void method() {
            //局部内部类
            class Da {
    
            }
        }
    
    }
    
    //一个java文件可以有多个class类,但只能有多个public  class
    class Ana {
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner inner = outer.new Inner();
            inner.getid();
            //没有名字初始化类,不用将实例保存
            new Test().eat();
            //匿名内部类
            new Listen() {
                @Override
                public void hello() {
    
                }
            };
        }
    
    }
    
    class Test {
        public void eat() {
            System.out.println(5);
        }
    
    }
    
    interface Listen {
        void hello();
    }
    

参考链接

8.JAVA-向上转型、向下转型 - 诺谦 - 博客园 (cnblogs.com)

posted @ 2021-09-07 16:32  貂蝉贼6  阅读(56)  评论(0)    收藏  举报