通过实例入门Java对象和类(OO 思想)

1、基本概念:
     1)封装:a.隐藏信息 b.使方法的实现细节不可见 c.统一对所有用户的接口 d.提高效率
     2)继承:通过已有的类去扩展新的类。
     3)多态:同一类域的不同对象在调用相同方法的时候表现不同的现象(针对对象的行为而言)。
2、方法的定义格式:

<modifiers><return_type><name>([argument_list>])[throws<exception>]{<block>}
     1)<modifiers>:访问修饰符(可以为若干个),没有先后顺序。例如 public staticstatic
public
private 等。
     2)<return_type>:方法的返回值类型(表示函数的出口),一个方法没有返回值时就必须定
义为 void,构造方法没有返回类型。
     3)<name>:方法名,方法名表示方法在代码区当中的地址。
     4)([<argument_list>]):,参数列表(表示函数的入口),可选
     5)[throw<exception>]:声明抛出的异常类型,可选
     6){<block>}:方法体(即方法中的执行的代码)。


3、参数的传递方式:按值传递;按引用传递
1) 8 种基本数据类型的参数传递:按值传递是对应参数的值拷贝的过程,因此不会改变传入参数的值(是将其对象复制一份)。
2) 引用类型的参数传递:按引用传递,有可能对所传入的“参数所指向的值”产生影响(是其对象的引用复制一份,并没有复制对象)。
3)Java 语言总是使用传值调用,这意味着方法得到的只是所有参数值的拷贝。因此对于基本数据类型的参数传递方法不能修改传递给它的任何参数变量的内容;而对于引用类型的参数传递的是传递该对象的引用,方法中并不能改变对象变量,但能通过修改该变量的引用修改其所指向的对象


4、this 关键字:当前对象的引用
1)当局部变量和实例变量出现命名冲突时,Java 中表现为就近原则,因而 java 处理这种
现象是使用 this.variableName 表示实例变量;
2)就两种用法:
     (1) this.variableName(实例变量) ---> 用于区分同名的实例变量和局部变量;
     (2) this(参数列表) ---> 用于调用本类的构造器。
3)关键字 this:是个隐式参数,代表被构造的对象

public class Person{
private String name;
public void setName(String name){
this.name=name; // this.name 为实例变量
}
}

4) 如果构造器的第一个语句具有形式 this(...),那么这个构造器将调用同一类中的其他构造器。
5) 在构造器中 this()必须放在方法的第一行。


5、封装
1)编码阶段的封装:
     1.数据隐藏(信息隐藏)private 修饰符
            a.类的编写者可以控制类的信息访问者(或类的使用者)的行为;
            b.当一个类的内部信息的表达方式发生变化时,它不会影响类的使用者。
     2.行为的不可见
            a.方法实现细节的不可见;
            b.统一的接口;
            c.增强可维护性。
2)编译阶段的封装:方法的重载
     条件:1.方法名必须相同(在同一类中有若干个方法相同);
     2.参数列表必须不同:表现在(1)参数个数不同 (2)参数类型不同 (3)参数顺序不同;
     3.返回类型无关紧要(返回值类型是否相同对重载没有任何的影响);
     4.Overloading 方法对于不匹配的参数是从低向高转换的:Byte—short—int—long—float—double
注意:1.在程序的编译过程中根据变量类型来找相应的方法,Overloading 被认为是“编译时的多态”
           2.Overloading 只是为方便程序员编程的解决方法,编译之后的方法名实际加上了各参数类型成为唯一的名字。


6、对象创建和初始化的过程(JVM 的工作)
1)在堆区开辟对象本身所在的存储空间,返回对象在堆区所在的地址给对象的引用(在栈区开辟对象的引用所在的存储空间);
2)对对象的属性进行默认初始化;
3)显式初始化;
      1.显式初始化:声明一个变量时同时对其赋值
      2.显式初始化可以帮助我们改变默认值,并可以给人为的实际变量赋予具有实际意义的值。
4)调用构造器对对象进行初始化(对象的构建过程中,目的是简化代码)。
      构造器:1.就是一个特殊的函数(人为的),生成对象的过程中调用的方法,但构造器并不能创建对象,也叫构造方法;
      2.特点:它的名字和类名完全相同;没有返回类型
      3.作用:能够让类的使用者提供一个初始化的值;就做一些初始化工作,初始化要求尽可能分离在其方法中,然后在构造器中调用。
      4.构造器调用:this()----->表示一个构造器调用本类中另外一个构造器。
      5.系统(编译器)在程序员没有创建构造器的情况下将自动生成默认的参数列表为空的,方法体也为空的构造器;如果程序员提 供了构造器,系统将不再提供默认的构造器。
      6.构造器的重载:可以构造多个构造器,但多个构造器的参数列表一定不同,参数顺序不同即属于不同的构造器。
      7.构造方法也可以是其他的限制符:private、protected、default 等(注意:private一般用在 singleton 模式中)。
      8.在一个对象的生成周期中构造器只用一次,一旦这个对象生成,那么这个构造器失效
      9.接口不能创建实例,因为没有构造器


7、继承(主要目的:代码复用)
1)条件:必须满足“is a”关系才可以继承;
2)语法:public class subclass extends superclass{...}
3)单根继承:不允许多重继承;一个子类只能有一个父类,但一个父类可以有若干个子类;JAVA 中所有类都有一个祖先类 Object(没有父类)
4)父类中的构造器不能继承,但可以被调用;方法和成员变量都可以被继承
5)Super 关键字: 表示父类数据区的引用
     1.也是个隐形参数,代表被构造对象的父类
     2.同样也必须在构造器的第一行
     3.就两种用法:
        (1)调用父类构造器:作为子类中的任何一个构造器必须调用父类中的构造器,表现为:
             a.显式调用:“super(传递给父类的参数值)”----->调用父类构造器并对其属性进行初始化,且必须放在构造器的第一                   行;
             b.隐式调用:如果在子类构造器中省略调用父类构造器的语法则编译器将自动插入代码 super()默认调用父类的无参构               造器,如果父类中不存在无参构造器的话,系统将会显示编译出错。
        (2)调用父类中的变量或方法:“super.父类的方法名()”----->调用父类中同名的方法(当子类中含有与调用父类方法同名          的方法时必须加“super.”,否则不用)。
        注意:当子类发现父类中的方法并不适合自己时,就要覆盖父类中的方法。
6)弊端: 1.减少了代码的灵活性
      2.破坏了耦合性原则——低耦合,高内聚


8、多态
1) 多态的概念:不同类型的对象虽然是相同的操作但执行的是不同的过程
2) 注意:对象的类型永远所固定的
3) 编译阶段看变量类型,运行阶段看对象类型
4) 运行期问题:具体调用哪个方法在运行阶段才能确立
5) 操作符 instanceof :
    1.语法:(引用型变量 instanceof 类名);
    2.涵义:判断引用型变量所指的对象是否是在操作符后的类的自身或者是它的子类中。
    3.返回结果是 boolean 型;
6) 转换:
    1.上朔造型:将子类类型变量转换成父类类型变量是隐式的;
    2.下朔造型:将父类类型转换成类类型是显式的(强制转换前需利用 instanceof 对其进行类型鉴定);
    显式转换成功的前提条件是被转换的变量所指向的对象类型一定要是转换以后类型的自身或者是它的子类。
7) 方法覆盖(Methods Overridden,也叫方法重写):
    1.范围:父子类之间
    2.条件:a.具有相同的方法名,相同的参数列表和相同的返回类型
                  b.可见范围不能被缩小(private 为最小的可见范围,public 为最大的可见范围,默认可见范围是位于二者之间的);

访问控制符:
权限高
public
全部可见
protected 本类可见,同包可见,子类可见
default 本类可见,同包可见
private 本类可见
权限低
c.异常不能被扩大(IOException 为比 Exception 小的异常)。
d.final 修饰的方法不能被重写。
e.静态方法不能被覆盖,但可以被子类中同名的方法所隐藏。
 

    3.切记:a.所有的属性取决于编译时类型;
                  b.所有的静态方法取决于编译时类型;
                  c.所有的普通方法取决于运行时类型(多态)。
8) 多态的三种表现形式:
    1. 父类 引用 = new 子类();
        接口 引用 = new 实现类();
    2. 方法声明:public void method(父类 参数){};
        方法调用:method(new 子类());
    3. public 父类 method(){
        return new 子类();
        }


9、面向对象与面向过程
1)对象的概念:
     1.什么是对象:EVERYTHING IS OBJECT(万物皆对象)
     2.所有的事物都有两个方面:
        a.属性(有什么):用来描述对象。
        b.方法(能够做什么):告诉外界对象有那些功能。“后者以前者为基础”
     3.一个对象的属性也可以是一个对象:这是一种对象的关联(associate)

public class Student{
private String name;---------对象
private int age;---------------基本类型
private boolean gender;
public void study(){}---------方法
}

2)为什么要使用面向对象:
     1.面向对象符合人类看待事物的一般规律。
            a.对象的方法的实现细节是屏蔽的,只有对象方法的实现者了解细节。
            b.方法的定义非常重要。方法有参数,也可能有返回值。分析对象主要从方法开始。通过类来看待对象,类是对象的抽                象。
            c.注意区分:对象(本身)、对象的实现者、对象的调用者。
     2.采用面向对象方法可以使系统各部分各司其职、各尽所能。
            a.对象之间的耦合性一定要低(比如不同硬盘和不同主板之间的关系),这样才能使每个对象本身做成最好的。
            b.对于对象的要求:高内聚、低耦合,这样容易拼装成为一个系统。实现高内聚就是要最大限度地提高复用性(复用性                好是因为高内聚)。可复用性是 OOP(面向对象编程)的基础。
3)比较面向过程的思想和面向对象的思想:
     1.面向过程的思想:由过程、步骤、函数组成,以过程为核心;
     面向对象的思想:以对象为中心,先开发类,得到对象,通过对象之间相互通信实现功能。
     2.面向过程是先有算法,后有数据结构。
     面向对象是先有数据结构,然后再有算法。
4)在用面向对象思想开发的过程中,可以对对象进行复用,如无法进行复用则开发新的对象。
     1.开发过程是利用简单对象的多个简单方法来实现复杂的功能。
     2.从语法上来看,一个类是一个新的数据类型。
     3.在面向对象编程中,除了简单数据类型,就是对象类型。

10、经典实例

1、一个基本类的编写

2、继承、重载、重写

static class Person {
        private String name;
        private boolean sex;
        private int age;

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

        //        重载
        public void change(String name) {
            this.name = name;
        }

        public void change(String name, boolean sex) {
            this.name = name;
            this.sex = sex;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", sex=" + sex +
                    ", age=" + age;
        }
    }

    static class Teacher extends Person {

        private double salary;

        //        无参构造
        public Teacher(String name, boolean sex, int age) {
            super(name, sex, age);
        }

        //        有参构造
        public Teacher(String name, boolean sex, int age, double salary) {
            super(name, sex, age);
            this.salary = salary;
        }

        //重写
        @Override
        public void change(String name) {
            super.change(name);
            this.salary += 1000;
        }

        @Override
        public String toString() {
            return super.toString() +
                    ", salary=" + salary +
                    '}';
        }
    }

    public static void main(String[] args) {
        Person p = new Person("soleil", false, 18);
        //        此时change会调用父类的方法
        p.change("yizhihanduxiu");
        System.out.println(p.toString());
        p.change("yizhihanduxiu",true);
        System.out.println(p.toString());
        Person t = new Teacher("soleil", false, 18);
        //        如果子类没有重写会直接调用父类的方法
        t.change("soleil1",true);
        System.out.println(t.toString());
        ((Teacher) t).salary = 7800;
        //        此时change会调用子类重写后的方法
        t.change("soleil1");
        System.out.println(t.toString());


    }

猜你喜欢

转载自blog.csdn.net/weixin_42363997/article/details/86214997