第三章面向对象编程

第三章面向对象编程

 

1.面向对象的设计思想

面向对象的基本思想是,从现实世界中客观存在的事物出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式。

面向对象更加强调运用人类在日常的思维逻辑中经常采用的思维方法与原则,如抽象、分类、继承、聚合、多态等

2.对象和类的概念

对象用计算机语言对问题域中事物的描述,对象通过属性(attribute)和方法(method)来分别对应事物所具有静态属性和动态方法。

类是用于描述同一类形的对象的一个抽象的概念,类中定义了这一类对象所应具有的静态方法和动态属性。

类可以看成一类对象的模板,对象可以看成该类的一个具体实例。

Java与面向对象

对象是java程序的核心,在java程序中“万事万物皆为对象”。

对象可以看成是静态属性(成员变量)和动态属性(方法)的封装体。

 

3.java类的定义

 

例子:

//class关键字定义一个类

public class Dog {

//成员变量定义

       static int furColor;

       float height;

       float weight;

       //方法定义

       void catchMouse(Mouse m) {

              //as;dfj;asdf

              //asdfj;asf

              //m.scream();

       }

      

       public static void main(String[] args) {

              //int i;

              //System.out.println(furColor);

              Dog d = new Dog();

              Mouse m = new Mouse();

              d.catchMouse(m);

              //HelloWorld hw = new HelloWorld();

       }

}

 

成员变量可以使java语言中任何一种数据类型(包括基本数据类型和引用数据类型)

在定义成员变量时可以对其初始化,如果不对其初始化,java使用默认的对其初始化如下:

数据类型取值为0char 取值‘\u0000’float 取值‘0.0F’ , double取值0.0D’,boolean 取值false ,所有引用类型取值为 null

成员变量的作用范围为整个类体。

 

对象的创建和使用

必须使用new 关键字创建对象。

使用对象(引用)·成员变量或来引用对象的成员变量

使用对象(引用)·方法(参数列表)来调用对象的方法。

同一个类的每个对象有不同的成员变量存储空间

同一类的每个对象共享该类的方法

 

4.构造方法(构造函数)

使用new  +  构造方法创建一个新的对象。

构造方法时定义在java类中的一个用来初始化对象的方法。

构造方法与类同名且没有返回值。

当没有指定构造方法时,编译器为类自动添加如:

类名(){}的构造方法。

构造方法但是你定义以后编译器就不给添加空白的构造方法了。

 

例子:

public  class Person {

int id ;

int age;

Person(int n , int i){

  id = n ;

  age = i;

}
}

例子:

class BirthDate {

    private int day;

    private int month;

    private int year;

   

    public BirthDate(int d, int m, int y) { //构造方法

        day = d;

        month = m;

        year = y;

    }

   

    public void setDay(int d) {

           day = d;

      }

     

    public void setMonth(int m) {

           month = m;

    }

   

    public void setYear(int y) {

           year = y;

    }

   

    public int getDay() {

           return day;

    }

   

    public int getMonth() {

           return month;

    }

   

    public int getYear() {

           return year;

    }

   

    public void display() {

           System.out.println

        (day + " - " + month + " - " + year);

    }

}

 

 

 class Test{

    public static void main(String args[]){

        Test test = new Test();

        int date = 9;

        BirthDate d1= new BirthDate(7,7,1970);//创建对象时,使用构造方法初始化对象的成员变量

        BirthDate d2= new BirthDate(1,1,2000);   

        test.change1(date);

        test.change2(d1);

        test.change3(d2);

        System.out.println("date=" + date);

        d1.display();

        d2.display();

    }

   

    public void change1(int i){

           i = 1234;

    }

   

    public void change2(BirthDate b) {

           b = new BirthDate(22,2,2004);

    }

   

    public void change3(BirthDate b) {

           b.setDay(22);

    }

}

// date=9

//7 - 7 - 1970

//22 - 1 – 2000

 

5.内存分析

栈内存:testxx   datexx  d1xx   d2xx

堆内存:7,7,1970  22,1,2000

 

6.方法重载

方法的重载是指一个类中可以定义有相同的名字,但是参数不同的多个方法。调用时,会根据不同的参数表选择对应的方法。

例子:

public class Test {

    void max(int a , int b) {

       System.out.println( a > b ? a : b );

    }

   

    void max(short a , short b) {

       System.out.println("short");

       System.out.println( a > b ? a : b );

    }

   

    void max(float a, float b) {

       System.out.println( a > b ? a : b );

    }

   

    public static void main(String[] args) {

       Test t = new Test();

       t.max(3, 4);

       short a = 3;

       short b = 4;

       t.max(a, b);

    }

}

//4

//short

//4

 

构造方法的重载

与普通方法一样,构造方法也可以重载

例子:

例子:

public class TestOverLoad {

       public static void main(String[] args) {

              Person p = new Person();

              Person p1 = new Person(400);

              Person p2 = new Person(2, 500);

              p.info();

              p.info("ok");

       }

}

 

class Person { 

      

       Person() {  //构造方法的重载

              id = 0;

              age = 20;

       }

      

       Person(int _id) {  //构造方法的重载

              id = _id;

              age = 23;

       }

      

       Person(int _id, int _age) {  //构造方法的重载

              id = _id;

              age = _age;

       }

      

  //成员变量定义

  private int id;

  private int age = 20;

  //方法定义

  public int getAge() {return age;}

  public void setAge(int i) {age = i;}

  public int getId() {return id;}

 

  void info() {

      System.out.println("my id is : " + id);

  }

 

  void info(String t) {

      System.out.println(t + " id " + id);

  }

}

 

// my id is : 0

//ok id 0

 

7.this关键字

在类中方法定义中使用的this关键字代表使用该方法的对象的引用。

当必须指出当前使用方法的对象是谁时要使用this

有时使用this可以处理方法中成员变量和参数重名的情况。

this可以看成是一个变量,它的值是当前对象的引用。

例子:

public class Leaf {

    int i = 0;

    Leaf (int i) {

        this.i = i;

    }

    Leaf increament(){

        i++;

        return this ;

    }

    void  print(){

        System.out.println("i = "+i);

    }

    public static void main(String[] args){

        Leaf  leaf = new  Leaf(100);

        leaf.increament().increament().print();

    }

}

//i = 102

 

8.static关键字

在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。

static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可以访问非static成员。

通过对象引用或类名访问静态成员。

例子:

public class Cat {

    private static int sid = 0;

    private String name;

    int id;

    Cat(String name) {

        this.name = name; 

        id = sid++;

    }

    public void info(){

        System.out.println

               ("My name is "+name+" No."+id);

    }

    public static void main(String arg[]){

 

        Cat.sid = 100;

        Cat mimi = new Cat("mimi");

        mimi.sid = 2000;

        Cat pipi = new Cat("pipi");

        mimi.info();

        pipi.info();

    }

}

//My name is mimi No.100

//My name is pipi No.2000

 

9.packageimport语句

package语句作为java源文件的第一条语句,指明该文件中定义的类所在的包。

格式:

package pkg1[.pkg2[.pkg3…]];

其中“.”来指明包的层次

执行一个类需要写全包名。

JDK中主要的包介绍如下:

Java.lang 包含一些java语言的核心类,如String MatchIntergerSystemThread提供了常用功能。

Java.awt 包含了构成抽象窗口工具集的多个类,这些类被用来构建和管理应用程序的图型用户界面(GUI

Java.applet 包含applet运行所需的一些类

Java.net 包含执行与网络相关的操作的类

Java.io 包含能提供多种输入/输出功能的类

Java.util 包含一些实用工具类,如定义系统特定、使用与日期日历相关的函数

 

10.类的继承

Java中使用extends关键字实现类的继承机制。

通过继承,子类自动拥有了基类(superclass)的所有成员(成员变量和方法)。

Java只支持但继承,不允许多继承,一个子类只能有一个基类,一个基类可以派生出多个子类。

 

例子:

class Person {

    private String name;

    private int age;

    public void setName(String name){this.name=name;}

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

    public String getName(){return name;}

    public int getAge(){return age;}

    public String getInfo() {

        return "Name: "+ name + "\n" +"age: "+ age;

    }

}

 

class Student extends Person { //继承

    private String school;

    public String getSchool() {return school;}

    public void setSchool(String school)

    {this.school =school;}

    public String getInfo() {

        return  "Name: "+ getName() + "\nage: "+ getAge()

                + "\nschool: "+ school;

    }

}

 

public class TestOverWrite {

    public static void main(String arg[]){

        Student student = new Student();

        Person person = new Person();

        person.setName("none");

        person.setAge(1000);

        student.setName("John");

        student.setAge(18);

        student.setSchool("SCH");

        System.out.println(person.getInfo());

        System.out.println(student.getInfo());

    }

}

// Name: none

//age: 1000

//Name: John

//age: 18

//school: SCH

 

11.访问权限

Java权限修饰符

修饰符     类内     同一包      子类        任何地方

private     yes

default     yes         yes

protected    yes         yes        yes        

public      yes          yes        yes         yes

对于class的权限修饰只可以用publicdefault

public类可以在任意地方被访问

default类只可以被同一个包内部的类访问

 

public class TestAccess {

}

 

class T {

    private int i = 0;

                  int j = 0;

    protected int k = 0;

    public int m = 0;

   

    public void m() {

       i = 9;

    }

}

 

class TT {

    public void m() {

       T t = new T();

       System.out.println(t.j);//根据是否出错来判断权限

    }

}

 

 

12.方法的重写

在子类中可以根据需要对从基类中继承来的方法进行重写。

重写方法必须和被重写方法具有相同方法姓名、参数列表和返回类型。

重写方法不能使用比被重写方法跟严格的访问权限。

 

例子:

class Person {

    private String name;

    private int age;

    public void setName(String name){this.name=name;}

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

    public String getName(){return name;}

    public int getAge(){return age;}

    public String getInfo() {

          return "Name: "+ name + "\n" +"age: "+ age;

  }

}

 

class Student extends Person {

    private String school;

    public String getSchool() {return school;}

    public void setSchool(String school)

    {this.school =school;}

    public String getInfo() {      //重写方法

      return  "Name: "+ getName() + "\nage: "+ getAge()

                    + "\nschool: "+ school;

              }

}

 

public class TestOverWrite {

public static void main(String arg[]){

        Student student = new Student();

        Person person = new Person();

        person.setName("none");

        person.setAge(1000);

        student.setName("John");   

        student.setAge(18);

        student.setSchool("SCH");

        System.out.println(person.getInfo());

        System.out.println(student.getInfo());

    }

}

 

13.super关键字

java类中使用super来引用基类的成分

例子:

class FatherClass {

    public int value;

    public void f(){

        value = 100;

        System.out.println

        ("FatherClass.value="+value);

    }

}

 

class ChildClass extends FatherClass {  //继承

    public int value;

    public void f() {

        super.f(); //引用父类方法

        value = 200;

        System.out.println

             ("ChildClass.value="+value);

        System.out.println(value);

        System.out.println(super.value);//引用父类成员变量

    }

}

 

public class TestInherit {

       public static void main(String[] args) {

              ChildClass cc = new ChildClass();

              cc.f();

       }

}

// FatherClass.value=100

//ChildClass.value=200

//200

//100

 

14.继承中的构造方法

子类的构造的过程中必须调用其基类的构造方法。

子类可以在自己的构造方法中使用super调用基类的构造方法,使用this调用本类的另外的构造方法,如果调用super,必须写在子类够造方法的第一行。

如果子类的构造方法中没有显示的调用基类构造方法,则系统默认调用基类无参数的构造方法。

如果子类构造方法中既没有显示调用基类的构造方法,而基类中又没有无参的构造方法,则编译错误。

例子:

class SuperClass {

    private int n;

    SuperClass() {

        System.out.println("SuperClass()");

}

 

    SuperClass(int n) {

        System.out.println("SuperClass(" + n + ")");

        this.n = n;

    }

}

 

class SubClass extends SuperClass { //继承

    private int n;

 

    SubClass(int n) {

        super();

        System.out.println("SubClass(" + n + ")");

        this.n = n;

    }

 

    SubClass() {

        super(300);

        System.out.println("SubClass()");

    }

}

 

public class TestSuperSub {

    public static void main(String arg[]) {

        SubClass sc1 = new SubClass(); //调用父类的无参构造方法

        SubClass sc2 = new SubClass(400); //调用父类的有参构造方法

    }

}

// SuperClass(300)

//SubClass()

//SuperClass()

//SubClass(400)

 

15.object

Object类是所有java类的根基类

如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object

   Public class Person{

         …..

}

等价于:

    Public class Person extends Object{

         …..

}

 

16. toString方法

Object类中定义有public String toString() 方法,其返回值是String类型,描述当前对象的有关信息。

在进行String与其它类型数据的连接操作时如:

System.out.println("info"+person),将自动调用该对象类的toString()方法

可以根据需要在用户自定义类型中重写toString()方法。

 

例子重写toString()方法:

public class TestToString {

       public static void main(String[] args) {

              Dog d = new Dog();

              System.out.println("d:=" + d);

       }

}

 

class Dog {

       public String toString() {

              return "I'm a cool dog!";

       }

}

//d:=I'm a cool dog!

 

17. equals方法

Object类中定义有

public Boolean equals(Object obj)方法

提供定义对象是否“相等”的逻辑

Objectequals方法定义为:x.equals(y)xy是同一个对象的应用时返回ture否则返回false.

 

例子:重写equals方法,String方法中重写了equals方法:

public class TestEquals {

    public static void main(String[] args) {

        Cat c1 = new Cat(1, 2, 3);

        Cat c2 = new Cat(1, 2, 6);

        System.out.println(c1 == c2);

        System.out.println(c1.equals(c2));

 

        String s1 = new String("hello");

        String s2 = new String("hello");

        System.out.println(s1 == s2);

        System.out.println(s1.equals(s2));

    }

}

 

class Cat {

    int color;

    int height, weight;

 

    public Cat(int color, int height, int weight) {

        this.color = color;

        this.height = height;

        this.weight = weight;

    }

 

    public boolean equals(Object obj) {  //重写equals方法

        if(obj == null) return false;

        else {

            if(obj instanceof Cat) {

                Cat c = (Cat)obj;

                if(c.color == this.color && c.height == this.height && c.weight == this.weight) {

                    return true;

                }

            }

        }

 

        return false;

    }

 

}

//false

//false

//false

//true

 

 

18.对象转型casting

一个基类的引用类型变量可以“指向”其子类的对象。

一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)。

可以使用引用变量instanceof类名来判断该引用型变量所“指向”的对象是否属于该类或该类的子类。

子类的对象可以当作基类的对象来使用称作向上转型(upcasting,反之称作向下转型(downcasting

 

 

19.多态

动态绑定是指:在执行期间(而非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

总结:1.要有继承2.要有重写3.父类引用指向子类对象

 

20.抽象方法,抽象类

abstract关键字来修饰一个类时,这个类叫做抽象类,用abstract来修饰一个方法时,该方法叫做抽象方法。

含有抽象方法的类必须被声明为抽象类,抽象方法必须被重写。

抽象类不能被实例化。

抽象方法只需要声明不需要实现。

例子:

abstract  class Animal {  //创建抽象类

    private String name;

    Animal(String name) {this.name = name;}

    public abstract void enjoy();

}

 

 class Cat extends Animal {      //继承

    private String eyesColor;

    Cat(String n,String c) {super(n); eyesColor = c;} //super引用父类方法

 

  public void enjoy() {         //重写父类方法

    System.out.println("猫叫声......");

  }

 }

 

class Dog extends Animal {

    private String furColor;

    Dog(String n,String c) {super(n); furColor = c;}

 

    public void enjoy() {

        System.out.println("狗叫声......");

    }

}

 

class Bird extends Animal {

    Bird() {

        super("bird");

    }

    public void enjoy() {

        System.out.println("鸟叫声......");

    }

}

 

class Lady {

    private String name;

    private Animal pet;

    Lady(String name,Animal pet) {

        this.name = name; this.pet = pet;

    }

    public void myPetEnjoy(){pet.enjoy();}

}

 

public class Test {

    public static void main(String args[]){

        Cat c = new Cat("catname","blue");

        Dog d = new Dog("dogname","black");

        Bird b = new Bird();

        Lady l1 = new Lady("l1",c); //父类指向子类对象,动物指向猫

        Lady l2 = new Lady("l2",d);// 父类指向子类对象,动物指向狗

        Lady l3 = new Lady("l3",b);// 父类指向子类对象,动物指向鸟

        l1.myPetEnjoy();

        l2.myPetEnjoy();

        l3.myPetEnjoy();

    }

}

//猫叫声......

//狗叫声......

//鸟叫声......

 

21.final关键字

Final的变量的值不能够被改变

Final的成员变量

Final的局部变量(形参)

Final的方法不能够被重写

Final的类不能够被继承

 

 

22.接口interface

接口(interface)是抽象方法和常量值的定义的集合。

从本质上讲,接口是一种特殊的抽象类,这种抽象类中包含常量和方法的定义,而没有变量和方法的实现。

接口的特性:

多个无关的类可以实现同一个接口。

一个类可以实现多个无关的接口。

与继承关系类似,接口与实现类之间存在多态性。

接口中声明属性默认为public static  final

接口中只能定义抽象方法,默认为public

接口可以继承其他的接口,并添加新的属性和抽象方法

例子:

public interface Runner{

  int id = 1;

  

  public void start();

 public void run();

public void stop();

 

}

猜你喜欢

转载自h389301776.iteye.com/blog/2198383