02-面向对象

类及对象

  1. 类的组成成分:

    • 属性(成员变量,Field)
    • 方法(成员方法,函数,Method)
  2. 属性

    • 成员变量 vs 局部变量
    • 相同点:
      • 遵循变量声明的格式: 数据类型 变量名 = 初始化值
      • 都有作用域
    • 不同点:
      • 声明的位置的不同 :成员变量:声明在类里,方法外, 局部变量:声明在方法内,方法的形参部分,代码块内
      • 成员变量的修饰符有四个:public private protected 缺省,局部变量没有修饰符,与所在的方法修饰符相同
      • 初始化值:一定会有初始化值,成员变量:如果在声明的时候,不显式的赋值,那么不同数据类型会有不同的默认初始化值。 局部变量:一定要显式的赋值。(局部变量没有默认初始化值)
        • byte short int long ==>0
        • float double ==>0.0
        • char ==>空格
        • boolean ==>false
        • 引用类型变量==>null
      • 二者在内存中存放的位置不同:成员变量存在于堆空间中;局部变量:栈空间中
    • 总结:
      • 按照数据类型的不同:基本数据类型(8种) & 引用数据类型
      • 按照声明的位置的不同:成员变量 & 局部变量
  3. 方法:提供某种功能的实现

    • 实例
    public void eat(){//方法体}
    public String getName(){}
    public void setName(String n){}
    //格式:权限修饰符 返回值类型(void:无返回值/具体的返回值) 方法名(形参){}
  • 关于返回值类型
    • void:表明此方法不需要返回值
    • 有返回值的方法:在方法的最后一定有return + 返回值类型对应的变量
  • 方法内可以调用本类的其他方法或属性,但是不能在方法内再定义方法!
  1. 面向对象编程的思想的落地法则一:
    • 设计并创建类及类的成分
    • 实例化类的对象
    • 通过“对象.属性”或"对象.方法"的形式完成某项功能
  2. 类的初始化的内存解析:内存划分的结构
    • 栈(stack):局部变量 、对象的引用名、数组的引用名
    • 堆(heap):new 出来的“东西”(如:对象的实体,数组的实体),含成员变量
    • 方法区:含字符串常量
    • 静态域:声明为static的变量

方法的重载(overload)

要求:
* 同一个类中
* 方法名必须相同
* 方法的参数列表不同(①参数的个数不同②参数类型不同)
补充:方法的重载与方法的返回值类型没有关系!

//如下的四个方法构成重载
//定义两个int型变量的和
public int getSum(int i,int j){
    return i + j;
}
//定义三个int型变量的和
public int getSum(int i,int j,int k){
    return i + j + k;
}
//定义两个double型数据的和
public double getSum(double d1,double d2){
    return d1 + d2;
}

//定义三个double型数组的和
public void getSum(double d1,double d2,double d3){
    System.out.println(d1 + d2 + d3);
}
//不能与如上的几个方法构成重载
//  public int getSum1(int i,int j,int k){
//      return i + j + k;
//  }
//  public void getSum(int i,int j,int k){
//      System.out.println(i + j + k);
//  }


//以下的两个方法构成重载。
public void method1(int i,String str){
    
}
public void method1(String str1,int j){
    
}

可变个数的形参的方法

  • .格式:对于方法的形参: 数据类型 ... 形参名
  • 可变个数的形参的方法与同名的方法之间构成重载
  • 可变个数的形参在调用时,个数从0开始,到无穷多个都可以
  • 使用可变多个形参的方法与方法的形参使用数组是一致
  • 若方法中存在可变个数的形参,那么一定要声明在方法形参的最后
  • 在一个方法中,最多声明一个可变个数的形参
//如下四个方法构成重载
    //在类中一旦定义了重载的可变个数的形参的方法以后,如下的两个方法可以省略
//  public void sayHello(){
//      System.out.println("hello world!");
//  }
//  public void sayHello(String str1){
//      System.out.println("hello " + str1);
//  }
    //可变个数的形参的方法
    public void sayHello(String ... args){
        for(int i = 0;i < args.length;i++){
            System.out.println(args[i] + "$");
        }
        //System.out.println("=====");
    }
    
    public void sayHello(int i,String ... args){
    //public void sayHello(String ... args,int i){
        System.out.println(i);
        
        for(int j = 0;j < args.length;j++){
            System.out.println(args[j] + "$");
        }
    }
    
    public void sayHello1(String[] args){
        for(int i = 0;i < args.length;i++){
            System.out.println(args[i]);
        }
    }
    

java的值传递机制

  • 方法的参数传递(重点、难点)
    • 形参:方法声明时,方法小括号内的参数
    • 实参:调用方法时,实际传入的参数的值
  • java中的参数传递机制:值传递机制
    • 形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量
    • 形参是引用数据类型的:将实参的引用类型变量的值(对应的堆空间的对象实体的首地址值)传递给形参的引用类型变量
  • 例一:
public static void main(String[] args) {
    TestArgsTransfer tt = new TestArgsTransfer();
    
    int i = 10;
    int j = 5;
    System.out.println("i:" + i + " j:" + j);//i : 10  j : 5
    
//      //交换变量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:" + m + " n:" + n);

}
  • 例二:
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;
        d.i = d.j;
        d.j = temp;
        System.out.println(d);//打印引用变量d的值
    }
}

class DataSwap{
    int i = 10;
    int j = 5;
}

面向对象的特征一:

封装与隐藏

  • 问题:当创建了类的对象以后,如果直接通过"对象.属性"的方式对相应的对象属性赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而是通过"对象.方法"的形式,来控制对象对属性的访问。实际情况中,对属性的要求就可以通过方法来体现
  • 面向对象思想的落地法则二:
    • 将类的属性私有化
    • 提供公共的方法(setter & getter)来实现调用
  • 四种权限修饰符
    • 权限从大到小为:public protected 缺省 private
    • 四种权限都可以用来修饰属性、方法、构造器
    • 修饰类的话:public 缺省

构造器

构造器的作用:①创建对象 ②给创建的对象的属性赋值

  • 设计类时,若不显式声明类的构造器的话,程序会默认提供一个空参的构造器

  • 一旦显式的定义类的构造器,那么默认的构造器就不再提供

  • 如何声明类的构造器。格式:权限修饰符 类名(形参){ }

  • 类的多个构造器之间构成重载

  • 类对象的属性赋值的先后顺序:

    • 属性的默认初始化
    • 属性的显式初始化
    • 通过构造器给属性初始化
    • 通过"对象.方法"的方式给属性赋值

this关键字

  • this:
    • 使用在类中,可以用来修饰属性、方法、构造器
    • 表示当前对象或者是当前正在创建的对象
    • 当形参与成员变量重名时,如果在方法内部需要使用成员变量,必须添加this来表明该变量时类成员
    • 在任意方法内,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的阅读性
    • 在构造器中使用“this(形参列表)”显式的调用本类中重载的其它的构造器,要求“this(形参列表)”要声明在构造器的首行!
public class TestPerson {
    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println(p1.getName() + ":" + p1.getAge());
        
        Person p2 = new Person("BB",23);
        int temp = p2.compare(p1);
        System.out.println(temp);
    }
}
class Person{
    
    private String name;
    private int age;
    
    public Person(){
        this.name = "AA";
        this.age = 1;
    }
    
    public Person(String name){
        this();
        this.name = name;
    }
    public Person(String name,int age){
        this(name);
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void eat(){
        System.out.println("eating");
    }
    public void sleep(){
        System.out.println("sleeping");
        this.eat();
    }
    //比较当前对象与形参的对象的age谁大。
    public int compare(Person p){
        if(this.age > p.age)
            return 1;
        else if(this.age < p.age)
            return -1;
        else
            return 0;
    }
    
}

package/import

package:声明源文件所在的包,写在程序的第一行
impotr:
- 显式导入指定包下的类或接口
- 写在包的声明和源文件之间
- 如果需要引入多个类或接口,那么就并列写出
- 如果导入的类是java.lang包下的,如:System String Math等,就不需要显式的声明
- 理解.*的概念。比如java.util.;
- 导入java.lang.
只能导入lang包下的所有类或接口,不能导入lang的子包下的类或接口
- import static 表示导入指定类的static的属性或方法

//import java.util.Scanner;
//import java.util.Date;
//import java.util.List;
//import java.util.ArrayList;
import java.lang.reflect.Field;
import java.util.*;
import static java.lang.System.*;
public class TestPackageImport {
    public static void main(String[] args) {
        out.println("helloworld");
        Scanner s = new Scanner(System.in);
        s.next();
        
        Date d = new Date();
        List list = new ArrayList();
        
        java.sql.Date d1 = new java.sql.Date(522535114234L);
        
        Field f = null;
    }
}

面向对象的特征二:

继承

  1. 继承的格式
    • 通过"class A extends B"类实现类的继承
  2. 子类继承父类以后,父类中声明的属性、方法,子类就可以获取到
    • 当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接调用罢了
    • 子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分
  3. java中类的继承性只支持单继承:一个类只能继承一个父类。反之,一个父类可以有多个子类

方法的重写(override orverwrite) vs 重载(overload)

  1. 重载:“两同一不同”:同一个类,同一个方法名,不同的参数列表注:方法的重载与方法的返回值无关!构造器是可以重载的
  2. 重写:(前提:在继承的基础之上,子类在获取了父类的结构以后,可以对父类中同名的方法进行“重构”)方法的返回值,方法名,形参列表形同;权限修饰符不小于父类的同名方法;子类方法的异常类型不大于父类的;两个方法要同为static或同为非static
class Cirlce{
   //求圆的面积
    public double findArea(){
   
    } 

}

class Cylinder extends Circle{
      //求圆柱的表面积
      public double findArea(){
      }
}

关键字 super

  1. super,相较于关键字this,可以修饰属性、方法、构造器
  2. super修饰属性、方法:在子类的方法、构造器中,通过super.属性或者super.方法的形式,显式的调用父类的指定属性或方法。尤其是,当子类与父类有同名的属性、或方法时,调用父类中的结构的话,一定要用“super.”
  3. 通过“super(形参列表)”,显式的在子类的构造器中,调用父类指定的构造器!
  4. 任何一个类(除Object类)的构造器的首行,要么显式的调用本类中重载的其它的构造器“this(形参列表)”或显式的调用父类中指定的构造器“super(形参列表)”,要么默认的调用父类空参的构造器"super()"
  5. 建议在设计类时,提供一个空参的构造器

子类对象实例化的全过程

public class TestDog {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.setAge(10);
        d.setName("小明");
        d.setHostName("花花");

        System.out.println("name:" + d.getName() + " age:" + d.getAge()
                + "hostName:" + d.getHostName());
        
        System.out.println(d.toString());
    }
}

// 生物
class Creator {
    private int age;

    public int getAge() {
        return age;
    }

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

    public Creator() {
        super();
        System.out.println("this is Creator's constructor");
    }

}

// 动物类
class Animal extends Creator {
    private String name;

    public String getName() {
        return name;
    }

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

    public Animal() {
        super();
        System.out.println("this is Animal's constructor");
    }

}

// 狗
class Dog extends Animal {
    private String hostName;

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public Dog() {
        super();
        System.out.println("this is Dog's constructor");
    }

}


面向对象的特征三:

多态

  1. 多态性的表现:①方法的重载与重写 ②子类对象的多态性
  2. 使用的前提:①要有继承关系 ②要有方法的重写
  3. 格式:
    • Person p = new Man();//向上转型
    • 通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法
  4. 编译时,认为p是Person类型的,故只能执行Person里才有的结构,即Man里特有的结构不能够调用,子类对象的多态性,并不使用于属性。
  5. 关于向下转型
    • 向下转型,使用强转符:()
    • 为了保证不报ClassCastException,最好在向下转型前,进行判断: instanceof
if (p1 instanceof Woman) {
            System.out.println("hello!");
            Woman w1 = (Woman) p1;
            w1.shopping();
        }

        if (p1 instanceof Man) {
            Man m1 = (Man) p1;
            m1.entertainment();
        }

  1. 详细可以参考:
    https://blog.csdn.net/sheepmu/article/details/38327205

学习地址

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容