美文网首页
【Java】面向对象——笔记

【Java】面向对象——笔记

作者: 感同身受_ | 来源:发表于2019-10-06 19:54 被阅读0次

    一、继承:

    1. java中只允许多层继承,不允许多重继承
    2. 继承的子类有时也称派生类,而被继承的类叫基类或父类(还有因为super关键字叫超类的)
    3. 子类是不能直接访问或调用父类中的私有成员的,但可以调用父类中的非私有方法
    4. 子类的实例化过程中,首先调用父类中的构造方法(默认)之后再调用子类自己的构造方法,因为在子类的构造方法中隐含了一个super()的语法
    5. super()调用的是父类的无参构造
    6. 3种访问权限:private<default<public
    7. 方法的覆写:被子类覆写的方法不能拥有比父类方法更加严格的访问权限(子类可以扩大权限,但是不能减小权限)
    8. 子类与父类声明了相同名称的属性,则在子类中直接访问的时候肯定是采用“就近原则”,即先找到本类种的属性,若是想调用父类的属性,则使用super调用
    import java.util.jar.Attributes.Name;
    class Person{
        private String name = "人";
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        public void print() {
            System.out.println("Person -> print(); ");
        }
        
    }
    class Student extends Person{
        private String name = "学生";
        @Override
        public void print() {
            System.out.println("Student -> print(),名字"+super.getName());
            //因为name属性在父类中为private,所以不能被子类调用或访问,只用通过public权限的getName()方法去访问
            //System.out.println("Student -> print(),名字"+super.name());
        }
    }
    public class OverrideDemo05 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            new Student().print();
        }
    
    }
    
    
    1. 重载(Overloading):方法名称相同,但参数类型和个数不同————对权限没要求————发生在同一个类中
      覆写(Overriding):方法名称、参数类型、个数全部相同————被覆写的方法不能拥有更严格的权限————发生在继承类中
    2. super关键字:访问父类的属性、方法、构造
      this关键字:遵循“就近原则”,在访问属性、方法时,先在本类中查找,若没有,再在父类中查找
      【注】不论this或是super,调用构造方法时,必须放在子类构造方法的首行
    3. final关键字:final声明的类不能有子类
      final声明的方法不能被子类覆写,但在权限允许的情况下,可以被子类调用
      final声明的变量即成为常量,常量不可修改
      【注】final声明变量时,要求全部的字母大写,例如:public static final String INFO = "CHINA";,如果一个程序中的变量使用public static final声明时,此变量将称为全局常量

    二、抽象类(abstract):

    抽象类的作用类似于模板,用来规范子类的格式,但是并不能直接由抽象类创建对象,只能通过抽象类派生出的新的类,再由它来创建对象。抽象类中也存在单继承的局限

    使用规则:
    1. 一个类中包含了抽象方法,那么这个类一定是抽象类(abstract class)
    2. 抽象类和抽象方法必须使用abstract关键字声明;
    3. 抽象方法只需要声明,不需要实现,如:public abstract void print();
    4. 抽象类必须被子类继承,子类必须覆写抽象类的全部抽象方法

    三、接口(interface):

    接口作为一种特殊的类,里面全是全局常量和公共的抽象方法所组成
    【注】在接口中,抽象方法必须定义成public权限,并且方法默认也是public,而不是default,且一个类可实现多个接口

    1. 继承父类和实现接口的语法:
      class 子类 extends 抽象类 implements 接口A,接口B,...{}
    2. JDK1.8之后,就允许接口可以定义普通方法(使用default声明)与静态方法(用static声明):
      default void fun(){//代码}
      static void get(){//代码}

    四、多态

    面向对象的主要表现:方法的重载与覆写、对象的多态

    1. 类型:
      向上转型:子类对象 --> 父类对象 格式:父类 父类对象 = 子类实例
      向下转型: 父类对象 --> 子类对象 格式:子类 子类对象 = (子类)父类实例
      【注】对于向上转型,程序会自动完成,而对于向下转型,必须要指明转型的子类类型
    class A{
        public void fun1() {
            System.out.println("A ---> fun()1");
        }
        public void fun2() {
    //      System.out.println("A ---> fun2()");
            this.fun1();
        }
    }
    class B extends A{
        @Override
        public void fun1() {
            System.out.println("B ---> fun1()");
        }
        public void fun3() {
            System.out.println("B ---> fun3()");
        }
    }
    public class PolDemo02 {
    
        public static void main(String[] args) {
            A a = new B();//向上转型  new B()为匿名对象
            //虽然是使用父类对象调用的fun1(),但实际上调用的方法是被子类覆写过的方法
            //即:如果对象发生了向上转型关系,所调用的方法肯定是被子类覆写过的方法
            a.fun1();
            //此时,父类对象通过this.fun1()也是调用的被子类覆写过的fun1()方法
            a.fun2();
            //此时对象a是无法调用子类B中的fun3()方法,因为fun3()只是子类的的方法
            //若要调用fun3(),必须使用B的对象
            
            //结论:当发生向上转型之后,父类对象所调用的方法是被子类覆写过的方法,若子类没有覆写,则调用的是自己原来的方法
            
            B b = (B)a; //向下转型
            b.fun1();//调用被自己类覆写的方法
            b.fun2();//因为没覆写,调用父类的fun2()方法
            b.fun3();//调用自己才有的fun3()方法
        }
    }
    
    

    【注】
    1.对象在向下转型之前,必须首先发生对象向上转型。否则将会出现对象转换异常
    2.一旦发生对象的向上转型之后,调用的方法肯定是被子类覆写过的方法

    五、instanceof

    //父类
    class A{
    }
    //子类B继承父类A
    class B extends A{
    }
    
    1. A a1 = new B(); //通过向上转型实例化A类对象此时,a1是通过子类实例化的对象,所以a1同时是子类和父类的实例,所以可以直接进行向上或向下转型
    2. A a2 = new A(); //通过A类的构造实例化本类对象,这样直接使用了父类实例化本类对象,则一定不再是子类的实例了,所以不能进行转换a2 instanceof B == false
    3. 在进行对象的向下转型关系之前,最好先进行判断之后再进行相应的转换操作,这样可以避免转换异常的出现
    if(a1 instanceof B){
        B b = (B)a1;//进行向下转型操作
    }
    

    【注】在类设计时,永远不要去继承一个已经实现好的类,只能继承抽象类或实现接口,因为一旦发生对象的向上转型后,所调用的方法一定是被子类所覆写过的方法

    六、抽象类和接口的应用

    1. 抽象类的实际应用:模板设计
      抽象类中定义的一个抽象方法,让子类必须去覆写它,这就相当与一个模板,你必须得有这个内容,其他得东西相当于你的补充说明
    2. 接口得实际应用:制定标准
      1.接口是java解决多继承局限得一种手段
      2.接口作为一种标准,是要求要实现这个接口的子类,需要进行这些操作,而不关心该子类是干嘛的
      3.没有任何方法的接口都叫标识性接口,便于了解实现这个接口的类是用于干嘛的
    3. 设计模式:
      A:适配器设计:一个类要实现一个接口,但又使用不完接口中的全部方法,所以需要一个Adapter(抽象类实现)去实现这个接口,再覆写这个接口中的方法,最后,子类就可以选择性的去覆写接口中的方法,否则,子类需要将接口中的方法全部实现
      B:工厂设计
    class Factory{
        public static Fruit getInstance(String className){
            Fruit f = null;
            if("apple".equals(className)){
                f = new Apple();
            }
        }
    }
    class main(){
        Fruit f = null;//定义接口对象
        f = Factory.getInstance("apple");//通过工厂去实例化对象
        f.eat();
    }
    

    【注】接口也能声明对象,但不可对其进行实例化,但可以让实现这个接口的子类去实例化这个对象

    Object类

    对于一个设计良好的类来说,最好覆写Object类中的equals()、hashCode()、toString()方法

    相关文章

      网友评论

          本文标题:【Java】面向对象——笔记

          本文链接:https://www.haomeiwen.com/subject/ptocyctx.html