Java学习之第三章——面向对象编程

学习面向对象(OOP)编程的三条主线

1.java类及类的构成成分:属性  方法  构造器  代码块  内部类

2.面向对象的三大特征(封装性 Encapsulation,继承性 Inheritance,多态性 Polymorphism,(抽象性))

3.其他关键字

OOP:Object Oriented Programming

面向过程:procedure oriented programming

理解一:人开门

面向过程:人 打开 门

面向对象:

人{

  打开(门){

    门.开开();

}

}

门{

 开开(){

  }

}

理解二:人把大象装进冰箱

面向过程:1)打开冰箱 2)把大象放进去 3)关闭冰箱

面向对象:

人{

 打开(冰箱){冰箱.开开()}

 操作(大象){大象.进入(冰箱)}

 关闭(冰箱){冰箱.合上()}

}

大象{

 进入(冰箱){}

}

冰箱{

开开(){}

合上(){}

}

类与类之间的关系:

关联关系,继承关系,聚合关系

Field=属性=成员变量,Method=(成员)方法=函数

一、面向对象思想的落地法则一:

      1.设计类,并设计类的成员(成员变量&成员方法)

      2.通过类,未创建类的对象(也称作类的实例化)

      3.通过“对象.属性”或“对象.方法”来调用,完成相应的功能

二、创建的多个对象,彼此各自拥有一套类的属性,当对其中一个对象的属性进行修改时,不会影响到其他对象的属性

//a3不意味着重新创建的一个对象,而是a1与a3公用一个对象实体

Animal a3=a1;

System.out.print("name"+a3.name+"age"+a3.age);

a3.name="维尼熊";

System.out.print("a1.name"+a1.name+"age"+a1.age);

三、类的属性(成员变量,Field)

  成员变量vs局部变量

相同点:1.遵循变量的声明格式。数据类型 变量名=初始化值

              2.都有作用域

不同点:1.声明的位置不同:成员变量:声明在类内,方法外

                                          局部变量:声明在方法内,方法的形参部分,代码块内

            2.成员变量的修饰符有四个:public private protected 缺省

               局部变量没有修饰符,与所在的方法修饰符相同

            3.初始化值:一定会有初始化值

               成员变量:如果在声明的时候,不显式的赋值,那么不同数据类型会有不同的初始化值

                 byte  short  int  long==>0

                 float  double  ==>0.0

                 char==>空格

                 boolean==>false

                 引用类型变量==>null

              局部变量:一定要显式的赋值。(局部变量没有默认初始化值)

          4.二者在内存中存放的位置不同:成员变量存在于堆空间中,局部变量:栈空间中

总结:关于变量的分类:1)按照数据类型的不同:基本数据类型(8种)&引用数据类型

                                      2)按照声明的位置不同,成员变量&局部变量

四、类的方法(函数,Method):提供某种功能的实现

public int getAge(){

   return age;

 //其后不可以声明语句

 //System.out.println("hello");

  类的访问机制:

在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。(例外:static方法访问非static,编译不通过。)

在不同类中的访问机制:先要访问类的对象,再用对象访问类中定义的成员。

方法重载(overload)的使用

要求 :1.同一个类中  2)方法名必须相同  3)方法的参数列表不同 (1.参数的个数不同  2.参数的类型不同)

补充:方法的重载与方法的返回值类型没有关系!

class Overload{

//以下四个方法之间都构成重载

   public int getSum(int i,int j){

         return i+j;

}

  public int getSum(int i,int j,int k){

         return i+j+k;

}

  public double getSum(double d1,double d2){

        return d1+d2;

}

  public void getSum(double d1,double d2,double d3){

        System.out.println(d1+d2+d3);

} 

//以下两个方法也构成重载

public void method1(int i,String str){

}

public void method1(String str1,int j){

}

}

类的初始化的内存解析

1)内存划分的结构:

   栈(stack):局部变量、对象的引用名、数组的引用名

   堆(heap):new 出来的“东西”(如:对象的实体,数组的实体),含成员变量                                                                            方法区:含字符串常量

   静态域:声明为static的变量

【匿名类对象】

创建的类的对象是 匿名的

 1)当我们只需要调用一次类的对象的时候,就可以考虑使用匿名的方式创建类的对象。

 2)特点,创建的匿名类的对象只能够调用一次!

class Circle{

  double radius;

  public double findArea(){

     return Math.PI*radius;

   }

public void setRadius(double r){

  radius=r;

}

public double getRadius(){

return radius;

}
public void show(){
  System.out.println("我是一个圆");
}

}
public class PassObject{
  public void printAreas(Circle c,int time){
    int temp=0;
   System.out.print("Radius"+"\t\t"+"Area");
   for(int i=1;i<=time;i++,temp=i){
      c.setRadius(i);
      System.out.print(c.getRadius()+"\t\t"+c.findArea());
  } 
  c.setRadius(temp);
}
public static void main (String[] args){
   PassObject p=new PassObject();
   Circle c=new Circle();//此时c为半径0
   p.printArea(c,5);

  System.out.println("now radius is "+c.getRadius());
  System.out.println();

  p.printArea(new Circle(),6);
  System.out.print("Radius"+"\t\t"+"Area");
  
  new Circle().show();
  new Circle().setRadius(2.3);//只能调用一次,堆空间没有名指向它,用完一次后回收
}
 



 

【可变个数的形参方法】

1.格式:对于方法的形参:数据类型...形参名

2.可变个数的形参的方法与同名的方法之间构成重载

3.可变个数的形参在调用时,个数从0开始,到无穷多个都可以。

4.使用可变多个形参的方法与方法的形参使用数组是一致的

5.若方法中存在可变个数的形参,那么一定要声明在方法形参的最后

6.在一个方法中,最多声明一个可变个数的形参

public class TestArgs{

  public static void main(String[]  args){

      TestArgs  t=new  TestArgs();

      t.sayHello();

     //t.sayHello(new String[]{"hello China","hello Beijing"})

  t.sayHello("hello China","hello Beijing")

     }

//如下四个方法构成重载

//在类中一旦定义了重载的可变个数的形参的方法以后,如下的两个方法可以省略(它们处理的方法一致)

  //public void sayHello(){

 //  System.out.println("hello world");

//}

//public void sayHello(String str1){

 //System.out.println("hello world"+str1);

//}

//可变个数的形参的方法

public void sayHello(String ... args){//可以跟第一,二个函数构成重载,若把第四个函数的方法名改为sayHello,则程序报错,它与第四个函数不构成重载

for(int i=0;i<args.length;i++){

 System.out.println(args[i]+"¥");

}

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

  }

public void sayHello(int i,String ... args){

   System.out.println(i);

  for(int i=0;i<args.length;i++){

    System.out.println(args[i]+"¥");

}

public void sayHello1(String[]  args){

for(int i=0;i<args.length;i++){

 System.out.println(args[i]);

}

}

//可变个数形参的使用的例子

//public  int  getSum(int i;int j){

  //return i+j;

//}

//public  int  getSum(int  i,int  j,int  k){

//  return i+j+k;

//}

public  int  getSum(int  ...  args){

  int sum=0;

  for(int i=0;i<args.length;i++){

  sum+=args[i];

}

return sum;

}

}

【方法的参数传递】

1.形参:方法声明时,方法小括号的参数

   实参:调用方法时,实际传入的参数的值

2.规则:java中的参数传递机制:值传递机制

   1)形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量

   2)形参是引用数据类型的:将实参的引用类型变量的值(对应的堆空间的对象实体的首地址值)传递给形参的引用类型变量

1)形参是基本数据类型的

public class TestArgsTransfer{
  public static void main(String[] args){
    TestArgsTransfer tt=new TestArgsTransfer();

     int i=10;
     int j=5;
     System.out.println("i"+i+"j"+j);
    
    //交换变量i与j的值
    //int temp=i;
    //i=j;
    //j=temp;
    tt.swap(i,j);//将i的值传递给m,j的值传递给n
  
    System.out.println("i:"+i+" j:"+j);//i:10 j:5
  }
//定义一个方法,交换两个变量的值
 public void swap(int m,int n){
    int temp=m;
    m=n;
    n=temp;
    System.out.println("m:"+n+" m:"+n);//m:5 n:10
}


2)形参是引用数据类型的

public class TestArgsTransfer1{
  public static void main(String[] args){
    TestArgsTransfer1 tt=new TestArgsTransfer1();
    DataSwap ds= new DataSwap();
    
    System.out.println("ds.i: "+ds.i+" ds.j"+ds.j);
 
    tt.swap(ds);
    System.out.println(ds);
  
    System.out.println("ds.i:"+ds.i+" ds.j:"+ds.j);
}
 //交换元素的值
 public void swap(DataSwap d){
   int temp=d.i;
   ds.i=d.j;
   d.j=temp;
   System.out.println(d);//打印引用变量d的值
}
}
class DataSwap{
  int i=10;
  int j=5;
}

【方法的值传递机制练习】


【面向对象的封装性】

面向对象的特征一:封装与隐藏

问题:当创建了类的对象以后,如果直接通过“对象.属性”的方式堆相应的对象赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而是通过“对象.方法”的形式,来控制对象属性的访问。实际情况 中,对属性的要求就可以通过方法来实现。

解决的方法:(封装性的思想)①将类的属性私有化 ②提供公共的方法(setter&getter)来实现调用。

public class TestAnimal{
  public static void main(String[] args){
    Animal a1=new Animal();
    //a1.name="花花";
    //a1.legs=-4;
    a1.setLegs(4);
    a1.setName("小花");

    a1.info();;
    a1.eat();
}


class Animal{
  private String name;//动物的名字
  private int legs;//腿的个数
  
  public void eat(){
    System.out.println("动物进食");
  }
  public void sleep(){
    System.out.println("动物睡觉");
  }
   public void info(){
    System.out.println("name:"+name+"  legs:"+legs);
  }
//设置类的属性(有形参无返回值)
  public void setLegs(int l){
    if(l>0&&l%2==0){
      legs=l;
   }else{
     System.out.println("您输入的数据有误!");
   }
  }
//获取类的属性(又返回值无形参)
  public int getLegs(){
    return legs;
 }
  public void setName(String n){
    //...
   name=n;
 }
 public String getName(){
  return name;
}
}

【权限修饰符】

public private 缺省(deaufult,可以不写) protected

可以用来修饰属性、方法

权限从小到大排列:

猜你喜欢

转载自blog.csdn.net/qq_41204918/article/details/83308715