黑马程序员-面向对象1

2014-11-02  本文已影响115人  狼孩

-------android培训java培训期待与您交流!----------

1.面向对象概念

a.面向对象概念


b.类与对象的关系

//定义类
    class People{
    //属性
    public int age;
    public string name;
    ...
    //定义方法 行为
    public int age()
    {
            return age;
    }
    //对象
    People p = new People();
    p.age();
    ...
new People().age = 23;
age(new People());

c.封装

d.构造函数

//定义类
class People{
    //默认构造函数
    People(){}
}

构造代码块

//定义类
class People{
    /**
     * 作用:给对象进行初始化
     * 特点:对象一建立就运行,而且优先于构造函数执行,针对所有的对象进行初始化都会先被执行一次。
     * 和构造函数的区别:
     *             构造代码块是给所有对象进行统一初始化。
     *             构造函数时给对应的对象进行初始化。
     * 用处:定义给不同对象的共性进行初始化。
     */
    {
        System.out.println("构造代码块");
    }
}

e.this关键字

    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
class People{
    private int age;

    /**
     * 构造函数
     * @param age
     */
    People(int age)
    {
        this.age = age;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }

    /**
     * 比较两个人的年龄是否相等。此处的this代表当前调用的对象的引用也就是p1。
     * @param p 人的对象变量
     * @return boolean
     */
    public boolean compare(People p)
    {
        return this.age == age;
    }

    
    public static void main(String[] args) {
        People p1 = new People(20);
        People p2 = new People(23);
        boolean b = p1.compare(p2);
        System.out.println("b = " + b);

    }
}
class People{
    private int age;
    private String name;

    /**
     * 空构造函数
     */
    People()
    {
    }

    /**
     * 构造函数
     * @param age
     */
    People(int age)
    {
        this();//调用People()构造函数
    }

    /**
     * 构造函数
     * @param age
     * @param name
     */
    People(int age, String name)
    {
        this(23);//调用People(int age)构造函数
        this.name = name;
    }

f.static关键字

    static String name;

    public static void main(String[] args) {
        System.out.println("People.name = " + People.name);
    }

静态的使用时间:

  • 静态变量(类变量)定义:当对象中的出现对象调用的共享数据时,该数据被静态所修饰存在于方法区中;对象中的特有数据定义成非静态存在于堆内存中。
  • 静态函数定义:当类中的某个功能没有访问到非静态数据(对象特有的数据),那么该功能可以定义成静态的(static)。
class People{
    String name;

    //没有关联到非成员变量name,那么这个函数可以设置成static的,方便后面直接通过类名调用
    public static void show()
    {
        System.out.println("没有访问到成员变量");
    }

    public static void main(String[] args) {
        //调用此方法时,与name没有关系。没有封装进数据。可以不建立对象来调用,设置成static的通过类名调用方便明了。
        People.show();
    }
}

静态代码块

    static
    {
        System.out.println("静态代码块");
    }

g.mian函数

public static void main(String[] args)

主函数是固定格式:JVM识别


h.对象初始化过程:
People p = new People("zhangsan", 23);

1.因为new用到了People.class,所以会先找到People.class文件并加载到内存中。
2.执行该类中的static代码块,如果有的话。再给People.class类进行初始化。
3.在堆内存中开辟空间,分配内存地址。
4.在堆内存中建立对象的特有属性,并进行默认初始化。
5.对属性进行显示初始化。
6.对对象进行构造代码块初始化。
7.对对象进行对应的构造函数初始化。
8.将内存地址赋给内存中的引用变量p。


i.继承
继承类 extends 被继承类
/**
 * Created by Sergio on 2014/11/2.
 */
public class ExtendsDemo1 {
    public static void main(String[] args) {
        Sun s = new Sun();
        s.show();
    }
}

class Parents{
    int num = 5;
}

//子继承父类
class Sun extends Parents{
    int num = 4;
    void show()
    {
        System.out.println(num);//访问的是子类的变量,相当于this.num
        System.out.println(super.num);//碰到同名变量可以使用super关键字访问父类的变量。
    }
}

B. 函数:当父类出现和子类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖掉。这也叫做覆盖(重写)。

/**
 * Created by Sergio on 2014/11/2.
 */
public class ExtendsDemo1 {
    public static void main(String[] args) {
        Sun s = new Sun();
        s.show();
    }
}

class Parents{
    int num = 5;
    void show()
    {
        System.out.println("被覆盖");
    }
}

//子继承父类
class Sun extends Parents{
    int num = 4;
    void show()
    {
        System.out.println(num);//访问的是子类的变量,相当于this.num
        System.out.println(super.num);//碰到同名变量可以使用super关键字访问父类的变量。
    }
}

覆盖注意点:子类覆盖父类,必须保证子类权限大于等于父类权限,才可以叫覆盖,否则编译失败。静态只能覆盖静态。
C. 构造函数:在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super()[会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();];

/**
 * Created by Sergio on 2014/11/2.
 */
public class ExtendsDemo2 {
    public static void main(String[] args) {
        Sun2 s2 = new Sun2(2);
        System.out.println(s2.x);//访问的是父类抽取的x = 4;
    }
}

class Parents2{
    int x = 4;
    Parents2()
    {
        System.out.println("fu run");
    }

    Parents2(int x)
    {
        System.out.println("x = " + x);
    }
}

//子继承父类
class Sun2 extends Parents2{
    Sun2()
    {
        //super();隐式的构造函数
        super(1);//根据父类构造函数来指定
        System.out.println("zi run");
    }

    Sun2(int x)
    {
        super(3);//根据父类构造函数来指定
        System.out.println("zi run");
    }
}

super语句一定定义在子类构造函数的第一行,初始化动作要先做。子类的所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问的构造函数。子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。


j. final关键字

k. 抽象类

l. 接口
/**
 * Created by Sergio on 2014/11/3.
 */
interface InterfaceDemo {
    public static final int NUM = 3;//变量定义
    public abstract void intefaceDemo();//方法定义
}


//接口必须被子类实现用关键字implements,接口可以被多个子类实现。子类也可以继承于一个父类。必须将接口中的所有方法实现因为接口中的方法都是抽象的
class InterfaceTest extends ExtendsDemo2 implements InterfaceDemo,InterfaceDemo2....{
    @Override
    public void intefaceDemo() {

    }
}

接口是不可以创建对象的,因为有抽象方法存在。需要被子类实现,覆盖接口中的抽象方法后,子类才可以实例化,否则子类是一个抽象类。
接口与接口之间的关系是继承关系,支持多继承关系。


m. 多态与关键字instanceof

一. 概念

二. 多态扩展性

  1. 多态的体现:父类的引用指向了自己的子类对象(父类)。
  2. 多态的前提:类与类之间有关系,有继承或者实现。
  3. 多态的益处:多态的出现提高了程序的扩展性,通常有前提条件是:存在覆盖。
  4. 多态的弊端:只能使用父类的引用访问父类中的成员。
  5. 多态中成员的特点:
    • 非静态成员函数:
      a. 在编译时期:参与引用型变量所属的类中是否有调用的方法,如果有编译通过,如果没有编译失败。
      b. 在运行时期:参与对象所属的类中是否有调用的方法。
      总结就是:成员函数在多态调用时,编译看左边,运行看右边。
    • 成员变量:
      无论编译和运行:都参考左边(引用型变量所属的类)
    • 静态成员函数(子类不覆盖父类方法,父类走父类,子类走子类。变量也一样。):
      无论编译和运行:都参考左边
/**
 * Created by Sergio on 2014/11/19.
 */
public class PolymorphicDemo {
    public static void main(String[] args) {
        //调用子类覆盖父类的eat()方法,有局限性在这点上
        function(new Dog());
        function(new Pig());
    }

    //定义共性的功能方法eat()
    public static void function(Animal a)
    {
        a.eat();
    }
}

/**
 * 集中抽象功能的父类Animal
 */
abstract class Animal{
    abstract void eat();
}


/**
 * 定义Dog类继承之Animal父类,并且拥有自己的特定功能类houseKeeping().
 */
class Dog extends Animal{
    //覆盖父类eat()方法
    public void eat()
    {
        System.out.println("Dog.eat");
    }

    //子类特有的方法
    public void houseKeeping()
    {
        System.out.println("看家");
    }
}


/**
 * 定义Pig类继承之Animal父类,并且拥有自己的特定功能类fat().
 */
class Pig extends Animal{
    //覆盖父类eat()方法
    public void eat()
    {
        System.out.println("Pig.eat");
    }

    //子类特有的方法
    public void fat()
    {
        System.out.println("养膘");
    }
}

三. 父类、子类类型转型

/**
 * Created by Sergio on 2014/11/19.
 */
public class PolymorphicDemo {
    public static void main(String[] args) {
        //类型提升,向上转型。将Dog类型提升为Animal类型
        Animal a = new Dog();
        a.eat();

        /**
         * 如果要调用子类特有的方法操作:强制将父类的引用转成子类类型,向下转型.将父类a引用强制转换成子类类型Dog。
         *
         * 注意:不能将父类对象转成子类类型。能转换的是父类指向了自己的子类对象时,该引用可以被提升也可以强制转换。
         * 多态始终都是子类在作者变化。
         */
        Dog d = (Dog)a;
        d.houseKeeping();

        //fun函数调用子类对象的功能
        fun(new Dog());
        fun(new Pig());
    }

    //提炼共性函数特征fun(Animal a)
    public static void fun(Animal a)
    {
        a.eat();

        /**
         * 判断传递进来的子类是那个对象的。使用关键字instanceof,判断左边对象是否属于右边类的实例,返回boolean
         * 类型数据。
         *
         * instanceof是一个二元操作符。使用的前提:1.子类型有限、2.对象需要做比较首先判断是否属于某个类的实例
         */
        if (a instanceof Dog){
            Dog d = (Dog)a;
            d.houseKeeping();
        }
        else if(a instanceof Pig)
        {
            Pig p = (Pig)a;
            p.fat();
        }
    }
}

/**
 * 集中抽象功能的父类Animal
 */
abstract class Animal{
    abstract void eat();
}


/**
 * 定义Dog类继承之Animal父类,并且拥有自己的特定功能类houseKeeping().
 */
class Dog extends Animal{
    //覆盖父类eat()方法
    public void eat()
    {
        System.out.println("Dog.eat");
    }

    //子类特有的方法
    public void houseKeeping()
    {
        System.out.println("看家");
    }
}


/**
 * 定义Pig类继承之Animal父类,并且拥有自己的特定功能类fat().
 */
class Pig extends Animal{
    //覆盖父类eat()方法
    public void eat()
    {
        System.out.println("Pig.eat");
    }

    //子类特有的方法
    public void fat()
    {
        System.out.println("养膘");
    }
}

四:小示例

package com.sergio.lianxi;

/**
 * Created by Sergio on 2014/11/20.
 *
 * 需求:电脑运行实例。电脑运行基于主板。
 */
public class PolymorphicDemo2 {
    public static void main(String[] args) {
        MotherBoard mb = new MotherBoard();
        mb.run();
        mb.usePCI(new SoundCard());
    }

}

/**
 * 电脑的各种部件基于电脑主板上的pci接口运行。模拟PCI接口。
 */
interface PCI{
    public void open();
    public void close();
}

//定义主板,运行的基础
class MotherBoard{
    public void run(){
        System.out.println("主板运行");
    }

    public void usePCI(PCI p)//接口型引用指向自己的子类对象
    {
        if(p != null)
        {
            p.open();
            p.close();
        }
    }
}


/**
 * 需要运行部件实现方式
 */
class SoundCard implements PCI
{
    @Override
    public void open() {
        System.out.println("声卡运行");
    }

    @Override
    public void close() {
        System.out.println("声卡关闭");
    }
}

2.设计模式

单例设计模式
package com.sergio.lianxi;

/**
 * 单例模式饿汉式。
 * 第一种方式。类一进内存就建立对象。
 * Created by Sergio on 2014/10/10.
 */
public class SinglePattern {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "SinglePattern{" +
            "age=" + age +
            '}';
    }

    //以下三个方法是单例使用的必须写法
    /**
     * 静态私有化本类的成员变量
     */
    private static SinglePattern instance = new SinglePattern();

    /**
     * 私有化构造方法,禁止对象实例化
     */
    private SinglePattern(){}

    /**
     * 对外提供一个公共的静态入口方法
     */
    public static SinglePattern getInstance()
    {
        return instance;
    }
}

class SinglePatternTest
{
    public static void main(String[] args) {

        SinglePattern s1 = SinglePattern.getInstance();
        SinglePattern s2 = SinglePattern.getInstance();
        s1.setAge(23);
        System.out.println("s2 = " + s2);
    }
}
package com.sergio.lianxi;

/**
 * Created by Sergio on 2014/10/10.
 * 单例模式懒汉式。也叫延迟加载式。只有调用了getInstance方法时,才建立对象
 */
public class SinglePattern2 {
    private static SinglePattern2 instance = null;
    private SinglePattern2(){}
    public static synchronized SinglePattern2 getInstance()
    {
if
        if(instance == null)
        {
            instance = new SinglePattern2();
        }
        return instance;
    }
}

注意:开发时候使用饿汉式,也就是第一种。

上一篇下一篇

猜你喜欢

热点阅读