首页 > 代码库 > Java 面向对象

Java 面向对象

类:

 是构造对象的模板或蓝图;

 类构造对象的过程称为创建对象的实例;

用Java编写的所有代码都位于某个类的内部;

封装:

  将实例域(属性)和方法包在一起;

  对对象的使用者隐藏了数据的实现方式;

  关键在于:绝对不能让类中的方法直接地访问其它类的实例域,程序仅通过对象的方法与对象数据进行交互;即使用方法将类的数据隐藏起来,控制其他类对该类的修改和访问数据的程度;就是说,一般获取、修改对象的属性都是通过方法来操作;

  对于每个特定的实例(对象)都有一组特定的实例域值,这些值的集合就是这个对象的当前状态;

  优点:针对域

    避免域被其他类的方法直接访问;(所以一般都定义为私有的,只通过本类中的方法进行调用和修改)

    可以改变内部实现,除了该类的方法之外,不会影响其他代码;

    更改器方法可以执行错误检查;

  注意:

    不要编写返回引用可变对象的访问器方法;如果需要返回一个可变对象的引用,应该首先对它进行克隆;

继承:

  子类会继承父类所有的内容(包括所有属性和方法,但不包括构造方法),但不一定能直接使用;

  java只支持单继承,extends后面只能跟一个类;

  举例:

   类B继承类A;

   类B创建的实例,可以调用和类A中相同的公有的方法和公有的实例域;但不能调用或设置类和A中相同的私有实例域和私有方法;

一个类的所有对象,每个对象都有自己的一份实例域,但所有对象共用那些方法;

继承的特性:

  1.当一个类继承自另一个类,子类中没有显式定义和父类相同的方法(方法名、参数、返回值都一样)时。用子类的对象调用方法时,会首先在子类中查找,如果子类中没有该方法,再到父类中查找。

  实例(1):

 1 public class Demo1
 2 {
 3     // 父类定义的 print()方法
 4     public void print()
 5     {
 6         System.out.println(123);
 7     }
 8 }
 9 
10 
11 public class Demo2 extends Demo1
12 {
13     // 子类没有显式定义和父类相同的方法(方法名、参数、返回值类型都一样)
14 }
15 
16 
17 public class Test
18 {
19     public static void main(String[] args)
20     {
21         Demo2 demo = new Demo2();
22         // 最后打印出的结果是 123
23         demo.print();
24     }
25 }

   实例(2):

public class Demo1
{
    // 父类定义的 print()方法
    public void print()
    {
        System.out.println(123);
    }
}


public class Demo2 extends Demo1
{
    // 子类显式定义和父类相同的方法(重写)
    public void print()
    {
        System.out.println(456);
    }
}


public class Test
{
    public static void main(String[] args)
    {
        Demo2 demo = new Demo2();
        // 最后打印出的结果是 456
        demo.print();
    }
}

  2.子类与父类之间构造函数的使用规则:

    (1).Java中每个类都有一个构造函数;如果类中没有显式定义构造函数,则编译器会默认提供一个无参构造函数;

   (2).子类继承父类时,必须在构造函数中调用父类的构造函数;

    (3).父类没有显式定义构造函数,只有一个默认的无参构造函数,那么子类继承父类时,也是通过在默认的无参构造函数调用父类的构造函数;

public class Demo1
{
    /**
     * 这是编译器默认提供的无参构造函数
     * 这个构造函数是隐藏的,看不到,现在让它显式出来只是为了看到无参构造函数的样子
     * 这里的super()调用的是 Object 类的构造方法
     * 父类并没有显式定义构造函数
     */
    public Demo1()
    {
        super();
    }
}


public class Demo2 extends Demo1
{
    /**
     * 子类继承父类,通过编译器提供的默认构造方法调用父类的构造方法
     * 这里构造方法也是隐藏的
     * 这里的 super() 调用的是 Demo1 类的构造方法
     */
    public Demo2()
    {
        super();
    }
}

 

      (4). 父类显示定义了带参(必须是带参)构造函数,那么子类继承父类时,也必须显示定义一个带参构造函数,在这个构造函数中调用父类的构造函数;

public class Demo1
{
    /**
     * 父类显示定义了一个带参构造函数
     */
    public Demo1(String s)
    {
        super();
        System.out.println(s);
    }
}


public class Demo2 extends Demo1
{
    /**
     * 子类必须显示定义一个带参构造函数来调用父类的构造函数
     * 这里的 super(s) 就是调用父类的带参构造函数,s是实参
     */
    public Demo2(String s)
    {
        super(s);
    }
}

 

    3.当一个方法只在父类中定义时,调用该方法时使用到的属性是父类的属性;如果该方法中又调用了其他方法,那么还是按照之前的顺序,先在子类中查找,再在父类中查找。

public class Demo1
{
    int x = 6;
    private int y = 2;

    public Demo1(int a)
    {
        x = a;
    }

    int getz()
    {
        int z;
        z = x / y;
        return z;
    }

    void show()
    {
        System.out.println("x=" + x);
        System.out.println("y=" + y);
        // 方法中调用了其它方法
        System.out.println("z=" + getz());
    }
}


public class Demo2 extends Demo1
{
    // 重新定义了 x,y 变量
    int x = 3, y = 5, z;

    public Demo2(int a)
    {
        super(a);
    }
    
    // 重写了 getz() 方法
    int getz() {
        z = x + y;
        return z;
    }
    
    // 定义独有的方法
    public void print()
    {
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        System.out.println("z = " + z);
    }
    
}


public class Test
{
    public static void main(String[] args)
    {
        Demo1 demo1 = new Demo1(10);
        Demo2 demo2 = new Demo2(9);
        demo1.show();
        /**
         * 打印出的结果:
         * x=9:子类 Demo2 通过构造方法将父类 Demo1 中的 x 属性值设为9,子类对象调用的
         * show() 方法在子类中没有重新定义(重写),调用的是继承自父类的 show()方法,
         * 则在父类中的 show() 方法中调用的 x 属性就是父类中的属性,值为 9;
         * y=2:同样的道理,子类调用的 show() 方法在子类中没有重新定义,所以 show() 方法
         * 中调用的 y 属性是父类中的 y 属性,值为 3;
         * z=8:show() 方法中的 getz() 方法在子类和父类中都有,则优先调用子类中的 getz()
         * 方法,那么子类中的getz()放用到的 x,y,z 属性就是子类中定义的 x,y,z 属性,x,y 的
         * 值分别为 3和5,所以 y 计算出来的值是 8;
         */
        demo2.show();
        /**
         * 调用子类特有的方法,那方法里面用的属性都是子类重新定义好的属性
         */
        demo2.print();
    }
}

// 最后打印出的结果:
// x=10
// y=2
// z=5
// x=9
// y=2
// z=8
// x = 3
// y = 5
// z = 8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Java 面向对象