zoukankan      html  css  js  c++  java
  • [JAVA学习笔记] 类与对象

    OOP的继承特性使OOP语言的代码具有可拓展性,拓展类也称为继承(inheritance)或子类化(subclass)。在Java中,默认情况下所有类都是可以拓展的,也可以使用final关键子来防止类被子类化。

    extends

    在类声明时我们使用extends关键字来拓展类,其位置位于子类名后,父类名前,例如:

    public class Child entends Parents{
        ......
    }
    

    所有没有拓展父类的Java类都将自动拓展java.lang.Object类作为父类,即Object是Java中的最终超类,在上面的代码中,Parents的父类就是Object

    is-a关系

    子类和超类具有is-a关系,例如Fruit类包含所有水果,那么Peach、Orange、Banana都是Fruit类的子类,因此Peach、Orange、Banana与Fruit便是is-a关系。
    is-a关系不可逆,我们可以说Peach是Fruit,但是不能说Fruit就是Peach,在代码中我们可以这么理解:

    public class Fruit{
        public void eat();  //Fruit具有eat的方法
    }
    
    class Peach extends Fruit{ //Peach是Fruit的子类
        public void pink();
        //Peach具有pink的方法,但是也继承了eat的方法
    }
    
    Fruit peach1 = new Peach(); //Peach是Fruit的子类,存在is-a关系
    Peach peach2 = new Peach();  //正常创建对象
    Peach fruits = new Fruit(); //由于is-a关系不可逆,因此这行代码是错误的!
    

    子类继承了其超类所有的公共方法和字段,以上面的代码为例,存在如下的情况:

    Peach aPeach = new Peach();
    aPeach.eat();  //Peach继承了Fruit的eat方法
    

    可访问性

    在子类中我们可以访问其超类的publicprotected级别的方法和字段,但是不能访问private级别的方法和字段,如果子类和超类位于同一个包中,子类也可以访问到超类默认级别的方法和字段。例如:

    public class A{
        public static int test1(){...};
        protected static int test2(){...};
        private static int test3(){...};
    }
    
    class B extends A{
        public void test(){
            test1();  //B可以访问到A的public方法
            test2(); //B可以访问到A的protected方法
            test3(); //B无法访问到A的private方法
        }
    }
    

    同时这种关系是子类与父类间的,我们无法通过A的子类B来访问到A的非公开方法,例如在上面的代码基础上:

    public class C{
        public static void main(String[] args){
            B obj = new B();
            obj.test2();  //无法编译,无法从外部访问A的protected方法
        }
    }
    

    重写与重载

    重载不等同于重写:方法的重写发生在父类与子类中,而重载发生在本类;重载的方法名必须相同,重写的方法名相同且返回值类型必须相同;重载的参数列表不同,重写的参数列表必须相同。

    方法重载

    方法重载的定义是如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载
    对于定义我们可以有以下的理解:

    • 方法名相同
    • 方法的参数类型,参数个数不同
    • 方法的返回类型可以不相同
    • 方法的修饰符可以不相同
    • main方法也可以被重载

    方法重载例子如下:

    public class Person {
    
        String name;   //name字段
        int age;     //age字段
    
        public Person(){   //无参构造方法,命名与类名一致
            this.name = "Jack";
            this.age = 18;
        }
    
        public Person(String name){    //重载 构造方法1(含一个参数name)
            this.name = name;
            this.age = 18;
        }
    
        public Person(String name, int age){  //重载 构造方法2(含两个参数name,age)
            this.name = name;
            this.age = age;
        }
    
        public static void main(String[] args) {
            Person mine = new Person();  //创建对象引用mine,此时调用 无参构造方法
            Person he = new Person("Lucy");  //创建对象引用he,此时调用构造方法1
            Person anybody = new Person("Helen", 3); //创建对象引用anybody,此时调用构造方法2
            System.out.println("My name is " + mine.name + " and age is " + mine.age);   //输出mine对象的字段
            System.out.println("His name is " + he.name + " and age is " + he.age);   //输出he对象的字段
            System.out.println("Your name is " + anybody.name + " and age is " + anybody.age);  //输出anybody的字段
        }
    
    }
    

    方法重写

    当拓展一个类时,我们可以在子类中修改父类的方法,这个操作便称为方法的重写,但是子类中编写的方法与父类的方法要具有相同的签名(相同返回类型,名称相同,参数列表相同)。需要注意的是重写时方法的权限可以从低到高,但是不能从高到低,也就是说,子类重写方法的权限不能低于父类被重写方法原本的权限
    权限的大小顺序如下:Public > Protected > 默认 > private
    和继承的权限特点是相同的,我们可以在子类中重写父类publicprotected级别的方法,如果父子类位于同一个包中,也可以重写默认级别的方法。

    public class Override{
        public static void main(String[] args){
            System.out.println("This is Class A print:");
            A a = new A();
            a.echo("Test");
            System.out.println("This is Class B print:");
            A b = new B();
            b.echo("Test");
        }
    
    }
    
    class A{
        public void echo(String str){
            System.out.println(str);
        }
    }
    
    class B extends A{
        public void echo(String str){
            System.out.println("Override is " + str);
        }
    }
    

    运行结果如下

    超类的调用

    我们可以通过super关键字来实现在子类中对超类成员的调用,以菜鸟教程的例程为例:

    class Country {
        String name;
        void value() {
           name = "China";
        }
    }
      
    class City extends Country {
        String name;
        void value() {
            name = "Shanghai";
            super.value();  //调用父类的方法
            System.out.println(name);
            System.out.println(super.name);
        }
      
        public static void main(String[] args) {
           City c=new City();
           c.value();
        }
    }
    

    调用超类的构造方法:

    class Person { 
    
        //构造方法(1) 
        Person() { 
            System.out.println("父类无参数构造方法"); 
        }
        
        //构造方法(2) 
        Person(String name) { 
           System.out.println("父类含一个参数的构造方法:" + name); 
        }
    } 
        
    public class Chinese extends Person { 
        Chinese() { 
           super();  //调用父类构造方法(1) 
           System.out.println("调用父类无参数构造方法"); 
        } 
        
        Chinese(String name) { 
           super(name); //调用父类具有相同形参的构造方法(2) 
           prt("调用父类含一个参数的构造方法:" + name); 
        } 
        
        
        public static void main(String[] args) { 
           Chinese cn = new Chinese(); 
           cn = new Chinese("codersai"); 
        } 
    }
    

    转换

    将子类的一个实例转换为他的父类类型,这个过程称为向上转换(upcast)。相反,将一个类的实例类型转换为其子类的类型便叫做向下转换(downcast)

    class Parents{
        ......
    }
    
    class Child extends Parents{
        ......
    }
    
    public class Cast{
        public static void main(String[] args){
            //向上转换
            Child child1 = new Child();
            Parents parents1 = child1;   //由Child类型的child1变为Parents类型的parents1
            //向下转换
            //只有当父类引用已经指向子类实例时才能进行向下转换
            Parents parents = child1;  //parents指向了Child的一个实例
            //向下转换强制要求在括号内写入子类型
            Child child2 = (Child) parents;  //由Parents类型的parents变为Child类型的child2
        }
    }
    

    final类

    类声明中,我们使用final可以使其变为最终类,无法被继续继承和拓展。

    instanceof

    instanceof运算符可以检验某个对象是否是指定的类型,常用于if语句中,例如

    public class Test{
        public static void main(String[] args){
            String a = "Ye";
            if (a instanceof java.lang.String){
                System.out.println("Yes");
            }else{
                System.out.println("No");
            }
        }
    }
    

    同时,子类也是属于其父类的类型,因此也可以判断一个实例是否属于某个父类类型中。

    class Parten{
        ......
    }
    
    class Child extends Partens{
        ......
    }
    
    public class Test{
        public static void main(String[] args){
            Child child = new Child();
            if (child instanceof Parents){  //判断child实例是否属于Parents类型
                System.out.println("Yes");
            }else{
                System.out.println("No");
            }
        }
    }
    

    [ * ]博客中转载的文章均已标明出处与来源,若无意产生侵权行为深表歉意,需要删除或更改请联系博主: 2245998470[at]qq.com

  • 相关阅读:
    loading加载动画
    js获取文本的行数
    获取浏览器结尾生成的参数,提交的时候对其做判断
    js获取当前浏览器地址栏的链接,然后在链接后面加参数
    a链接在新窗口打开
    js随机出现2个数字
    css进行中打点效果
    jqeury显示前几个,隐藏后几个,点击后隐藏前几个显示后几个
    jQuery 源码解析(七) jQuery对象和DOM对象的互相转换
    jQuery 源码解析(六) $.each和$.map的区别
  • 原文地址:https://www.cnblogs.com/yesec/p/15240944.html
Copyright © 2011-2022 走看看