Java第三章面向对象过程

三、面向对象编程

(一)

1.面向对象与面向过程

   定义:面向对象是相对于面向过程而言的。面向过程,强调的是功能行为。面向对象,将功能封装进对象,强调具备了功能的对象

 

一.面向对象的落地法则一:
1.设计类,并设计类的成员(成员变量&成员方法)
2.通过类,来创建类的对象(也称作类的实例化)
3.通过“对象.属性”或“对象.方法”来调用,完成相应功能。

类的实例化在内存的结构

 

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

 

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

四.类的方法
1)格式:权限修饰符  返回值类型(void:无返回值/具体的返回值)  方法名(形参){}
2)关于返回值类型:有返回值的方法:在方法的最后一定有return + 返回值类型对应的变量

 

2.类与类之间的关系

    1.关联关系:关联体现的是两个类之间语义级别的一种强依赖关系,属于强耦合。这种关系比依赖强、不存在依赖关系的偶然性、关联关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。体现在代码上是,类A中有类B中的成员变量。

  

  class abstract class AbstractGun{ 

        //抽象射击方法 
        public void shoot(); 
}
class Rifle extends AbstractGun{
//设计射击方法实现 public void shoot(){      System.out.println("步枪射击");

     }
}
class Soldier{

     //定义士兵的枪支
  private AbstractGun gun;

  public void setGun(AbstractGun _gun){
    this.gun=_gun;
  }
  public void killEnemy(abstractGun gun){

       System.out.println("士兵开始杀人");
       gun.shoot();
  }
  
  }

  class client{

     public static void main(String [] args){
        Soldier solder=new Soldier();
        solder.setGun(new Rifle());
        solder.killEnemy();
     }
  }
    //类client与类soldier是依赖关系,
    //类soldier与类AbstractGun是一种关联关系。Soldier中有AbstractGun的类变量
    //类Rifle与类AbstractGun是一种继承关系

 

 

 

    2.继承关系(泛化关系)

    3.聚合关系:聚合是关联关系的一种特例,体现在整体与部分到的关系,即has-a的关系。此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。比如计算机与CPU、公司与员工的关系等。表现在代码上与关联关系是一致的。

    4.实现关系:实现指的是一个类实现interface接口的功能。从类指向实现的接口。

    5.依赖关系:类A使用到类B,但这中使用关系是具有偶然性、临时性的,属于弱耦合。 
在代码上体现在,类A中含有类B的局部变量

    A中方法名(Class B){  }

  

    6.组合关系:组合也是关联关系的一种特例,体现的是一种contains-a的关系,这种关系比耦合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体声明周期结束意味着部分生命周期结束。

 

3.面向对象思想的概述

  类:对一类事物的面熟,是抽象的、概念上的定义

  对象:实际存在的该类食物的每个个体,因而也称实例

 

4.属性:对应类中的成员变量
   行为:对应类中成员方法

 

5.方法的重载overload

  要求:1.求同一个类中

        2.方法名必须相同

     3.方法的参数列表不同(①参数的个数不同②参数的类型不同)
       补充:方法的重载与方法的返回值类型没有关系。
       参数个数相同,参数的类型相同,但顺序不同依然能构成重载。
  

public class Person {
    private String name;
    private int age;
    
    public void eat(){
        System.out.println("人吃饭");
    }
    public void eat(String name){
        System.out.println(this.name + "吃饭");
    }
    public void eat(String name,int age){
        System.out.println(this.name + this.age + "吃饭");
    }
    public void eat(int age,String name){
        System.out.println(this.age + this.name + "吃饭");
    }
}

 

 

 

 

6.匿名对象

  匿名类对象:创建的类的对象是匿名的
    1)当我们只需要一次调用类的对象时,我们就可以考虑使用匿名的方式创建类的对象
    2)特点:创建的匿名类对象只能调用一次。
new XXX({});

 

public void test1(){
        new Son(){

            public void show() {
                // TODO Auto-generated method stub
                System.out.println("跳舞");
            }
            
        }.show();
    }
}
class Son{

}

 

 

 

 

7.可变个数的形参的方法

可变个数的方法
1.格式:对于方法的形参:数据类型 ...形参名
2.可变个数的形参的方法与同名的方法之间构成重载
3.可变个数的形参再调用时,个数从0开始,到无穷个都可以
4.使用可变多个形参的方法的形参使用数组是一致的
5.若方法中存在可变个数的形参,那么一定要声明在方法参数的最后。
6.在一个方法中,最多声明一个可变的形参

 

    @Test
    public void test2(){
        Person p =new Person();
        p.eat(1);//吃
        p.eat(2,"ss","sw");//qwe
        p.eat(3,"awq","wd","aw","rt");//ss
    }

class Person{
    private String name;
    private int age;
    public void eat(int age){
        System.out.println("吃");
    }
    
    public void eat(int age,String name1,String name2){
        System.out.println("qwe");
    }
    
    public void eat(int age,String... name){
        System.out.println("ss");
    }
}

 

 

 

 

8.方法的参数传递

1.形参:方法声明时,方法小括号内参数
   实参:调用方法时,实际传入的参数的值

2.规则:java中的参数传递机制:值传递机制
    1)形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量
    2)形参是引用数据类型的:将实参的引用数据类型变量的值(对应的堆空间的对象实体的首地址)传递给形参的引用类型变量

交换数组中指定位置的元素:交换arr数组中索引为i和j的两个元素

3.存储结构

 

9.类的成分之三:构造器

构造器(constructor 构造方法) contruction CCB  ICBC oop


构造器的作用:①创建对象②给创建的对象的属性赋值
1.设计类时,若不显式声明类的构造器的话,程序会默认提供一个空参的构造器
2.一旦显式的定义类的构造器,那么默认的构造器就不再提供。
3.如何声明类的构造器,格式:权限修饰符  类名(形参){}
4.类的多个构造器之间构成重载

 

class Son{
    private String name;
    private int age;
    private int banji;
    
    public Son() {//构造器
        super();
        // TODO Auto-generated constructor stub
    }
    public Son(String name, int age, int banji) {
        super();
        this.name = name;
        this.age = age;
        this.banji = banji;
    }
    public Son(String name){
        super();
        this.name = name;
    }
        
}

 

 

 

 

10.类对象的赋值

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

1.静态属性初始化

2.静态代码块初始化
3.属性的默认初始化
4.属性的显式初始化

5.通过构造器给属性初始化
6.通过“对象.方法”的方式给属性赋值

 


    @Test
    public void test3(){
        //5.通过构造器给属性初始化
        Son s2 = new Son("小王",9,3);
        Son s1 = new Son();
        //6.通过“对象.方法”的方式给属性赋值
        s1.setName("小明");
    }

class Son{ //1.静态属性初始化 private static String name = "小赵"; //4.属性的显式初始化 private int age = 0 ; //3.属性的默认初始化 private int banji; //2.静态代码块初始化 static{ name = "小张"; } public Son() { super(); // TODO Auto-generated constructor stub } public Son(String name, int age, int banji) { super(); this.name = name; this.age = age; this.banji = banji; } public Son(String name){ super(); this.name = name; } public static String getName() { return name; } public static void setName(String name) { Son.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getBanji() { return banji; } public void setBanji(int banji) { this.banji = banji; } }

 

 

 

 

 (二)面向对象三大特征:

 1.封装:

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

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

 

class Car{
    private String name;
    private int age;
    private String carname;
    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 String getCarname() {
        return carname;
    }
    public void setCarname(String carname) {
        this.carname = carname;
    }
    
}

 

 

 

 

 2.继承:

注:toString()方法显示在堆空间的地址值

<1>继承的定义

继承性
1.为什么要设计继承性?
2.通过"class A extends B"类实现类的继承
子类:A 父类(或基类SuperClass):B
3.子类继承父类以后,父类中声明的属性、方法,子类就可以获取到
    明确:当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接调用
    
    子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分

    extends:子类是对父类功能的“扩展”,明确子类不是父类的子集。

4.java类的继承只支持单继承,一个类只能继承一个父类,一个父类可以有多个子类。
5.子父类只是相对的概念

 

class Person{
    private String name;
    private int age;
    public void eat(){
        System.out.println("吃");
    }
    
}
class Man extends Person{
    private String name;
    private int age;
    public void sleep(){
        System.out.println("睡觉");
    }
}

 

 

 

 

<2>方法的重写

方法的重写 -----(方法的重载)修饰符  返回值类型  方法名  (参数列表){}
1.前提:有子类继承父类
2.子类继承父类以后,若父类的方法对子类不使用,那么子类可以对父类的方法重写(override overwrite)
3.重写的规则: 1)要求子类方法的“返回值类型 方法名(参数列表)”与父类的方法一样
               2)子类方法的修饰符不能小于父类方法的修饰符
               3)若父类方法抛异常,那么子类方法抛的异常类型不能大于父类的
               4)子父类的方法必须同为static或同为非static的。

 

class Person{
    private String name;
    private int age;
    public void eat(){
        System.out.println("吃");
    }
    
}
class Man extends Person{
    private String name;
    private int age;
    public void sleep(){
        System.out.println("睡觉");
    }
    public void eat(){
        System.out.println("男人吃饭");
    }
}

 

 

 

<3>super

super:可以用来修饰属性、方法、构造器
1)当子类与父类中有同名的属性时,可以通过"super.此属性"显式的调用父类中声明的属性。
若想调用子类的同名的属性"this.属性"
2)当子类重写父类的方法以后,在子类中若想在显式的调用父类的被重写的方法,就需要使用"super.方法"
3)super修饰构造器,通过在子类中使用"super(形参列表)"来显式的调用父类中指定的构造器。
    >在构造器内部,"super(形参列表)"必须声明在首行。
    >在构造器内部,"this(形参列表)"或"super(形参列表)"只能出现一个。
    >在构造器中,不显式的调用"this.(形参列表)"或"super(形参列表)"其中任何一个,默认调用的是父类空参的构造器。
    建议:设计一个类时,尽量要提供一个空参的构造器。

 

    public void test3(){
        Man m1= new Man();
        m1.sleep();
    }

class Person{
     String name;
     int age;
    
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println("吃");
    }
    
}
class Man extends Person{
     String name;
     int age;
     
    public Man(String name){
        super("xia",2);//调用person有参构造器
        
    }
     
    public Man(String name, int age) {
        super();
        super.name = name;//调用父类的属性
        this.age = age;
    }
    public Man() {
        super();
        // TODO Auto-generated constructor stub
    }
    public void sleep(){
        System.out.println("睡觉");
    }
    public void eat(){
        System.out.println("男人吃饭");
    }
    public void read(){
        super.eat();//调用父类的方法
    }
}

 

 

 

 

 <4>子类对象实例化的全过程

 

3.多态

 多态性
1.多态性指的是什么?多态性,可以理解为一个事物的多种表型形态
    1)方法的重载和重写2)子类对象的多态性
2.子类对象的多态性使用的前提:①要有类的继承②要有子类对父类方法的重写

3.程序运行分为编译状态和运行状态
对于多态性来说,编译时:"看左边",将此引用变量理解为父类的类型
运行时,"看右边",关注于真正对象的实体,子类的对象,那么执行的方法就是子类重写的。

子类对象的多态性:父类的引用指向子类对象
Person p1 = new Man();(向上转型)
虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的时子类重写父类的方法
p1.eat();
p2.eat();
man对象的方法

子类特有的方法不能调用,调用的是重写的方法。
Person p2 = new  Woman();
p2.eat();
p2.walk();
p2.shopping();//错的
Woman w = (woman)p2;(向下转型)
w.shopping();//对的
Woman w1 = (Woman)p1;
w1.shopping();//不会报错,运行时,转化异常。
instanceof判断引用数据类型
格式:对象a instanceof 类A
判断a是否是类A的一个实例,是的话,返回true,否则返回false
若a是A类的实例,那么a也一定是A类的父类的实例。

 

 其他关键字:

 

1.this关键字
(1,可以用来修饰属性、方法、构造器
(2.this理解为当前对象或当前正在创建的对象,比如:this.name,this.show();
(3.可以在构造器中通过“this(形参)”的方式显示的调用本类中的其他重载的指定的构造器。
    要求:1.在构造器的内部必须声明在首行
            2.若一个类中有n个构造器,那么最多有n-1个构造器中使用了this();

2.javabean

JavaBean是一种Java语言写成的可重用组件。
标准:
1.类是公共的
2.有一个无参的公共的构造器
3.有属性,且有对应的get,set方法
+表示public类型 -表示private类型 #表示protected类型

 

3.package

package:声明源文件所在的包,写在程序的第一行
每“.”一次,表示一层文件目录
包名都要小写

 

4.import

 import:
1)显式导入指定包下的类或接口
2)写在包的声明和源文件之间
3)如果需要引入多个类或接口,那么就并列写出
4)如果导入的类是java.lang包下的,如:system String Math就不需要显式的声明
5)理解.*的概念
6)如何处理同名类的导入。如:在util包和sql包下同时存在Date类
7)import static 表示导入指定类的static的属性或方法
8)导入java.lang.*只能导入lang包下的所有类或接口,不能导入lang的子包下的类或接口

猜你喜欢

转载自www.cnblogs.com/yangHS/p/10699716.html