Java核心技术初阶04:面向对象思想、类和对象

1.面向对象思想

1.1

  • 现实世界是由对象和对象之间相互作用共同组成的
  • 每个对象有自己的特有属性,也有自己专有的方法。外部对象想要调用这些方法,可以向它请求并传入参数,等方法执行结束后,返回结果。
  • 对象=属性+方法
  • 对象的规范=属性定义+方法定义

对象调用过程:
1.输入参数;
2.等待目标方法执行结束;
3.返回结果

1.2

Java中,引入对象和类的概念

  • 对象是一个变量(具体的东西)
  • 类就是类型(是规范、是定义),从万千对象中抽取共性
  • 类规定了对象应该有的属性内容和方法
  • 对象是类的距体表现,是活生生的
  • 例如:土豆丝菜谱是类,一盘土豆丝是对象

1.3

  • 从程序发展的角度来理解,OO(Oriented Object:面向对象)是对OP(Oriented Procedure:面向过程)的一种改进
  • OP的典型代表是C和Pascal。更强调方法动作,所有的变量是被动参与进来,没有自主决定权
  • OO的方法输语每个对象的。能否实现是由每个对象说了算的,有主人翁精神

1.4

  • OP的例子
public class OPExample {
    public static void main(String[] args) {
        int a, b, c;
        a = 1;
        b = 2;
        c = add(a, b);
        System.out.println("c is " + c);
    }

    // 函数定义
    public static int add(int m, int n) {
        return m + n;
    }
}

方法是主体,所有的参数是类似于宾语.

  • OO的例子
public class OOExample {
    private int a;

    public void setA(int a) {
        this.a = a;
    }

    public int add(int b) {
        return this.a + b;
    }

    public static void main(String[] args) {
        int b = 5;
        OOExample obj = new OOExample();
        obj.setA(10);
        System.out.println(obj.add(b));
    }

}

方法从属于一个对象,而这个对象可以执行自身的某个方法.
obj.add(b):主语obj,谓语add,宾语b

Java核心技术初阶04:面向对象思想、类和对象_第1张图片

  • 计算机的发展和社会发展也是相似之处
    • 更强调方法的执行主体
    • 增加类型的重用部分(内容和行为)

1.5

  • 变量定义的变迁:更加功能强大
  • 基本类型(一种变量)=>>结构体(多种变量捆绑)=>>类(多种变量+方法)
  • 类可以继承;子类可以继承父类所有内容(不能直接访问private成员)
    • 基本类型无法做到
    • 结构体只能做到全包含,不能控制包含粒度

short和int都是整数类型,但是没有继承关系,只是表示的整数范围不同而已。

1.6

  • 基本变量例子:int a; float b;
  • 结构体变量例子
// c语言结构体不能包含函数
struct Simple{
	int a;
	double b;
};//成员默认均为public

struct Complex{
	char c;
	struct Simple foo;
	//Complex必须包含Simple所有内容
};

Complex包含:int a,float b,char c

  • 类/对象例子:
public class Father {
    private int money=100;//私有
    long mobile=1399999999L;

    public void hello(){
        System.out.println("hello");
    }
}

//--------------------------------------------

public class Son extends Father {
    public void hi(){
        //子类可以扩展自己的成员方法
        System.out.println("hi !!!!!");
    }

    public static void main(String[] args){
        Son s=new Son();
        System.out.println(s.mobile);//Son没有定义mobile,而是通过父类继承的
        //  System.out.println(s.money);//error 父类的money是私有的,子类无法直接访问

        s.hello();// Son没有定义f1,而是通过父类继承的
        s.hi();//Son可以自定义自己的成员方法
    }
}

子类必须通过父类的方法才能访问父类的私有变量。

1.7

  • OO最早的始于Simula 67,成形于20实际70年代Smalltalk
  • 当前最主要的代表是C++和Java
  • 面向对象语言主要特点:
    • 识认性:辨识/认定为一种对象
    • 类别性:好几种对象可以归为一类
    • 多态性:是指在这个类别里面,这些对象有一定的共同性,也有一定的不同性
    • 继承性:每个子类都会继承父类的所有东西,然后可以使用它们

1.8总结

  • OO总结
    • 现实世界是由对象和对象之间相互作用共同组成的
    • 对象不仅包含成员变量,还有成员方法
    • 对象的内容可以继承

2.Java类和对象

2.1

  • 最简单的类class A{}//没有任何属性和行为
  • 对象 A obj = new A();
  • 类是定义,是规范,是“死‘的东西
  • 对象是实例,是类的一个实现,是一个具体的东西
  • 例如:
    • 类等价于一个土豆丝菜谱
    • 对象是根据类制作出的对象,等价于一盘土豆丝
      Java核心技术初阶04:面向对象思想、类和对象_第2张图片

2.2

  • A obj1 = new A(); A obj2 = new A();
  • 以上有 2个对象,它们的类型都是 A,但是这是两个不同的对象,在内存中有不同的放地址。因此,没有两个对象是完全一样的。
    Java核心技术初阶04:面向对象思想、类和对象_第3张图片

2.3

  • A obj = new A();
  • obj 可以看作是内存中一个对象 (包括若干个数据)的句柄
  • 在C/C++中, obj称为指针,在 Java 中称为 Reference(参考)
  • 对象赋值是Reference 赋值,而基本类型是直接值拷贝
  • 参看例子ReferenceTest.java 和ArgumentPassingTest.java ,来查看基本类型赋值和普通对象赋值的不同
    Java核心技术初阶04:面向对象思想、类和对象_第4张图片
// MyNumber
class MyNumber
{
	int num = 5; 
}

// ReferenceTest 
public class ReferenceTest {

	public static void main(String[] args) {
		
		int num1 = 5;
		int num2 = num1;
		System.out.println("num1: " + num1 + ", num2: " + num2);
		num2 = 10;
		System.out.println("num1: " + num1 + ", num2: " + num2);
		
		
		MyNumber obj1 = new MyNumber();
		MyNumber obj2 = new MyNumber();
		System.out.println(obj1.num);
		System.out.println(obj2.num);
				System.out.println("======接下来输出新值ֵ=====");

		obj2 = obj1;
		obj2.num = 10;
		
		System.out.println(obj1.num);
		System.out.println(obj2.num);

	}
}

Java核心技术初阶04:面向对象思想、类和对象_第5张图片Java核心技术初阶04:面向对象思想、类和对象_第6张图片Java核心技术初阶04:面向对象思想、类和对象_第7张图片

// ArgumentPassingTest 
public class ArgumentPassingTest {

	public static void main(String[] args) {
		int a = 1, b = 2;
		swap(a,b);
		System.out.println("a is " + a + ", b is " + b);  //a=1, b=2
		
		MyNumber obj1 = new MyNumber();
		MyNumber obj2 = new MyNumber();
		obj2.num = 10;
		swap(obj1, obj2);
		System.out.println("obj1 is " + obj1.num + ", obj2 is " + obj2.num);  //  obj1  10,   obj2  5

	}
	// int型是直接赋值的
	public static void swap(int m, int n)
	{
		int s = m;
		m = n;
		n = s;
	}
	public static void swap(MyNumber obj3, MyNumber obj4)
	{
		int s = obj3.num;
		obj3.num = obj4.num;
		obj4.num = s;
	}

}

Java核心技术初阶04:面向对象思想、类和对象_第8张图片
调用swap(a,b);在内存里出现a和b,以及m和n,都是单独的数字,m和n的交换不影响a和b

2.4

  • 产生一个对象, A obj = new A();
    • 99% 的情况是用new关键字,还有 1% 是用克隆和反射生成
  • new出对象后,内部属性值默认是? 例子Initialization.java
    • short 0 int long 0L
    • boolean false
    • char ‘\u0000‘(’\u0000‘相当于一个空格)
    • byte 0
    • float 0.0f
    • double 0.0d

public class Initialization {
	
	boolean v1;
	byte v2;
	char v3;
	double v4;
	float v5;
	int  v6;
	long v7;
	short v8; 
	
	
	public static void main(String[] args) {
		Initialization obj = new Initialization();
		System.out.println("The initial value of boolean variable is " + obj.v1);
		System.out.println("The initial value of byte variable is " + obj.v2);
		System.out.println("The initial value of char variable is " + obj.v3);  //\u0000 space
		System.out.println("The initial value of double variable is " + obj.v4);
		System.out.println("The initial value of float variable is " + obj.v5);
		System.out.println("The initial value of int variable is " + obj.v6);
		System.out.println("The initial value of long variable is " + obj.v7);
		System.out.println("The initial value of short variable is " + obj.v8);
		
		int a;
		// System.out.println(a);  //error, a 没有初始化

	}

}

Java核心技术初阶04:面向对象思想、类和对象_第9张图片

2.5 总结

  • 类是规范,对象根据产生出的实例
  • 基本型别赋值是 拷贝赋值,对象赋值是reference赋值
  • 类成员变量有初值,函数临时变量必须初始化

3.构造函数

3.1

  • 如何在对象产生时就给成员变量赋值呢
  • 答案就在构造函数里,constructor function
public class A {
	int id;
	
	public A(int id2) {
		id = id2;
	}
}
  • A obj = new A(10);会调用构造函数

构造函数没有返回值
public void A(int id2)不是构造函数,而实普通函数

3.2

  • Java构造函数的名称必须和类名一样,且没有返回值
  • Java有构造函数,但是没有析构函数
    • 构造函数是制造对象的过程,析构函数是清除对象的过程
  • 每个变量都是有生命周期的,它只能存储在离它最近的一
    对{}中
    • 参看LifeCycleTest.java
public class LifeCycleTest {

	public static void main(String[] args) {
		int a=0;  // a 在main函数中都是active
		
		//i只能活在for循环中
		for(int i=0; i<5; i++) {
			int k = 0;
			k++;
		}
		
		if(a>0) {
			Object obj1 = new Object();  //obj1 只能在if分支中
			System.out.println("a is positive");
		} else {
			Object obj2 = new Object();  //obj2 只能else分支中
			System.out.println("a is non-positive");
		}
	}
}

每一个变量,都只能存活于离它最近的一对大括号当中

  • 当变量被创建时,变量将占据内存;当变量消亡时,系统
    将回收内存

3.3

  • Java具有内存自动回收机制的,当变量退出其生命周期后,
    JVM会自动回收所分配的对象的内存。所以不需要析构函 数来释放内存
  • 对象回收效率依赖于垃圾回收器GC(Garbage Collector),
    其回收算法关系到性能好坏,是JVM的研究热点。

3.4

  • 每个Java类都必须有构造函数。
  • 如果没有显式定义构造函数,Java编译器自动为该
    类产生一个空的无形参构造函数。如果已经有了显
    式的有参构造函数,编译器就不会越俎代庖了。
    Java核心技术初阶04:面向对象思想、类和对象_第10张图片Java核心技术初阶04:面向对象思想、类和对象_第11张图片
  • 每个子类的构造函数的第一句话,都默认调用父类
    的无参数构造函数super(),除非子类的构造函数第
    一句话是super,而且super语句必须放在第一条,
    不会出现连续两条super语句。(本条规则在后续继
    承时会再提到)

3.5

  • 一个类可以有多个构造函数,只要形参列表不相同
    即可。

函数重载(overload),函数名相同,形参不同

  • 在new对象的时候,根据实参的不同,自动挑选相应
    的构造函数。如果实参形参匹配不上,将会报错。
  • 查看例子ConstructorTest.java
class MyPairNumber
{
	int m;
	int n;
	public MyPairNumber()
	{
		m = 0;
		n = 0;
	}
	public MyPairNumber(int a)
	{
		m = a;
		n = 0;
	}
	public MyPairNumber(int a, int b)
	{
		m = a;
		n = b;
	}	
}
public class ConstructorTest {

	public static void main(String[] args) {
		MyPairNumber obj1 = new MyPairNumber();
		MyPairNumber obj2 = new MyPairNumber(5);
		MyPairNumber obj3 = new MyPairNumber(10,20);
		System.out.println("obj1 has " + obj1.m + "," + obj1.n);
		System.out.println("obj2 has " + obj2.m + "," + obj2.n);
		System.out.println("obj3 has " + obj3.m + "," + obj3.n);

		// A a = new A();  //error, A类中没有无参数的构造函数
	}
}

多个class可以写在一个.java文件中,但是最多只能由一个类时public class,并且public class类的名字必须和.java的文件名相同
如果类由构造函数,编译器不会自动增加无参的空的构造函数

3.6 总结

  • 构造函数是一个对象初始化的过程。
  • 一个类必须有构造函数,可以有多个构造函数。在new的
    时候根据实参和形参进行匹配。
  • Java只有构造函数,没有析构函数。

4 信息隐藏和this

4.1 信息隐藏原则1

  • 面向对象有一个法则:信息隐藏
    • 类的成员属性,是私有的private;
    • 类的方法是公有public的,通过方法修改成员属性的值。
  • 打个比方:朋友再熟悉,也不会到他抽屉直接拿东西,而
    是通过他的公开接口来访问、修改东西。
// InfoHiding 
class InfoHiding {
	private int id;

	public InfoHiding(int id2) {
		id = id2;
	}
	public int getId() {
		return id;
	}
	public void setId(int id2) {
		id = id2;
	}
}
// InfoHidingTest 
public class InfoHidingTest {
	public static void main(String[] args) {
		InfoHiding obj = new InfoHiding(100);
		obj.setId(200);
		System.out.println(obj.getId());
	}
}

信息隐藏:通过类的方法来间接访问类的属性,而不是直接访问类的属性

4.2 信息隐藏原则2

  • 类成员是私有private的
  • get和set方法是公有public的,统称为getter和setter
  • 外界对类成员的操作只能通过get和set方法
  • 可以用Java IDE快速生成
public class Person {
	private int height;
	private int weight;
	private int age;
	private String name;
	
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

4.3 this(1)

  • this负责指向本类中的成员变量
// InfoHiding
class InfoHiding {
	private int id;

	public InfoHiding(int id2) {
		id = id2;
	}
	public int getId() {
		return id;
	}
	public void setId(int id2) {
		id = id2;
	}
}

// InfoHiding2 
public class InfoHiding2 {
	private int id;
	
	public InfoHiding2(int id)
	{
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
}

Java核心技术初阶04:面向对象思想、类和对象_第12张图片在InfoHiding2 的构造函数里,形参的优先级更高

4.4 this(2)

  • this负责指向本类中的成员方法
    • this.add(5,3); //调用本类的add方法, this可忽略
      在不影响歧义的情况下,this可以省略
  • this可以代替本类的构造函数
    • this(5); //调用本类的一个形参的构造函数
  • 参看ThisTest.java
// ThisTest 
public class ThisTest {

	public static void main(String[] args) {
		MyPairNumber obj = new MyPairNumber(5);
				
		System.out.println(obj.sum());
	}
}

// MyPairNumber 
public class MyPairNumber {
	private int m;
	private int n;
	public int getM() {
		return m;
	}
	public void setM(int m) {
		this.m = m;
	}
	public int getN() {
		return n;
	}
	public void setN(int n) {
		this.n = n;
	}	
	public MyPairNumber()	{
		this(0, 0);
	}	
	public MyPairNumber(int m)	{
		this(m, 0);
	}	
	public MyPairNumber(int m, int n)	{
		this.m = m;
		this.n= n;
	}	
	public int sum() {
		return this.add(m,n);  //return add(m,n);  also ok
	}
	public int add(int a, int b){
		return a+b;
	}	
}


this:指向本类中的成员变量;指向本类中的成员方法;可以当作构造函数使用

4.5 总结

  • 信息隐藏原则
    • 保护属性信息
    • 公开行为信息
  • this负责指向本类中的成员
  • this可以代替本类的构造函数

你可能感兴趣的:(Java,java)