《 高淇Java300集视频》:【3】面向对象基础

 

面向过程(Procedure Oriented)和面向对象(Object Oriented,OO)都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。

面向对象编程,是一种通过对象的方式,把现实世界映射到计算机模型的一种编程方法。

 

一、类与对象

类(Class):是对一类事物的描述 ,是抽象的 、概念上的定义。由属性(Field)、方法(Method)和构造方法(Constructor )组成。

对象(Object):是实际存在的该类事物的每个个体,因而也称为实例(instance)。

如:“书”是一种抽象的概念,所以它是类,而《Java核心技术》、《Java编程思想》是对象。

 

1.1、定义类

语法:

修饰符 class 类名 {
    //属性声明
    //方法声明   
}

 

 1 /**
 2  * 测试定义类
 3  * @author 林
 4  *
 5  */
 6 public class TestStudent {
 7     String name;    //属性声明
 8     int age;
 9     
10     void study() {    //方法声明
11         System.out.println("学习中");
12     }
13 }

 

1.2、创建对象

语法:

修饰符 数据类型 属性名 = 初始化值 ;

 

// 测试创建对象
TestStudent s=new TestStudent();

 

1.3、属性

数据类型 初始化默认值
整型 0
浮点型 0.0
字符型 '\u0000'
布尔型 false
所有引用类型 null

 

 

 

 

 

 

 

 

Java 语言中除基本类型之外的变量类型都称之为引用类型。

 

1.4、修饰符

  同一个类 同一个包 子类 所有类
private × × ×
default(默认) × ×
protected ×
public

 

 

 

 

 

 

 

1.5、内存分析

堆( Heap):存储对象实例

栈( Stack): 存储局部变量

方法区(Method Area) :存储类信息、 常量、 静态变量、 静态方法、代码

 

二、方法

 语法:

修饰符 方法返回类型 方法名(方法参数列表) {
        若干方法语句;
        return 方法返回值;
}

 

2.1、参数

方法可以包含0个或任意个参数。方法参数用于接收传递给方法的变量值。调用方法时,必须严格按照参数的定义一一传递。

可变参数用类型...定义,可变参数相当于数组类型。

1 class Group {
2     String[] names;
3  
4     public void setNames(String... names) {
5         this.names = names;
6     }
7 }

 

// 测试可变参数
Group g=new Group();
g.setNames();               //传0个参数
g.setNames("林一");         //传1个参数
g.setNames("林一","林二");    //传2个参数

 

【1】基本类型参数传递,传递的是数值。

 1 // 测试基本类型参数传递
 2 public class Main {
 3     public static void main(String[] args) {
 4         Person p = new Person();
 5         int n = 15;
 6         p.setAge(n);     //setAge()方法获得的参数,复制了n的值给p.age,后面n改变不影响p.age
 7         System.out.println(p.getAge()); // 打印15
 8         n = 20;
 9         System.out.println(p.getAge()); // 打印15
10     }
11 }
12 
13 class Person {
14     private int age;
15  
16     public int getAge() {
17         return this.age;
18     }
19  
20     public void setAge(int age) {
21         this.age = age;
22     }
23 }

 

【2】引用类型参数的传递,传递的是对象地址。

 1 // 测试引用类型参数的传递
 2 public class TestMethod {
 3     public static void main(String[] args) {
 4         Person p=new Person();
 5         String[] f=new String[] {"林一","林二"};
 6         p.setName(f);  //数组是一个对象,传入数组只是传引用地址
 7         System.out.println(p.getName());
 8         f[1]="林三";  //修改数组元素
 9         System.out.println(p.getName());  //引用地址没变,数组元素改变,结果也改变
10     }
11 }
12  
13 class Person{
14     private String[] name;
15     
16     public String getName() {
17         return this.name[0]+" "+this.name[1];
18     }
19     
20     public void setName(String[] name) {
21         this.name=name;
22     }
23 }

 

2.2、方法重载(Overload)

方法名相同,但各自的参数不同,称为方法重载。

注意:方法重载的返回值类型通常都是相同的。

方法重载的目的是,功能类似的方法使用同一名字,更容易记住,因此,调用起来更简单。

 

2.3、构造方法

构造方法(constructor),是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。

【构造方法要点】:

  1. 通过new关键字调用。

  2. 构造方法有返回值,但不能定义返回值类型,不能在构造器里使用return返回某个值。

  3. 如没有定义构造方法,则编译器会自动定义一个无参的构造方法。如已定义则编译器不会自动添加。

  4. 构造器的方法名必须和类名一致。

 

 1 package com.test;
 2 /**
 3  * 测试定义构造方法
 4  * @author 林
 5  *
 6  */
 7 public class TestStu {
 8     public static void main(String[] args) {
 9         Stu s=new Stu("林一",17);        // 创建对象会自动调用构造方法
10         System.out.println(s.getName());
11     }
12 }
13  
14 class Stu{
15     private String name;
16     private int age;
17     
18     public Stu(String name,int age) {    //定义构造方法
19         this.name=name;
20         this.age=age;
21     }
22     
23     public String getName() {
24         return this.name;
25     }
26     
27     public int getAge() {
28         return this.age;
29     }
30 }

 

【1】默认构造方法

如一个类没有定义构造方法,编译器会自动为我们生成一个默认构造方法,它没有参数,也没有执行语句。

如自定义了一个构造方法,那么,编译器就不再自动创建默认构造方法。

 

【2】构造方法重载(Overload)

构造方法重载,根据不同参数区别不同得构造方法。

 1 /* 测试构造方法重载 */
 2 class Person {
 3     private String name;
 4     private int age;
 5  
 6     public Person(String name, int age) {
 7         this.name = name;
 8         this.age = age;
 9     }
10  
11     public Person(String name) {
12         this.name = name;
13         this.age = 12;
14     }
15  
16     public Person() {
17     }
18 }

 

2.4、equals与==方法

Object 的 equals 方法默认就是比较两个对象的hashcode,是同一个对象的引用时返回 true 否则返回 false。

==代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。

【eclipse把光标放String类,按ctrl键+点击鼠标左键看类源码】

 1 package com.test;
 2  
 3 /**
 4  * 测试equals与==方法
 5  * @author 林
 6  *
 7  */
 8  
 9 public class TestEquals {
10     public static void main(String[] args) {
11         Person p1=new Person();
12         Person p2=new Person();
13         System.out.println(p1==p2);    //false
14         System.out.println(p1.equals(p2));    //false
15         
16         String s1=new String();
17         String s2=new String();
18         System.out.println(s1==s2);    //false
19         System.out.println(s1.equals(s2));    //true,equals重构过
20     }
21 }
22  
23 class Person{
24     int id;
25     String name;
26     public void showName() {
27         System.out.println(id+" "+name);
28     }
29 }

 

2.5、toString方法

Object类中定义有public String toString()方法,其返回值是 String 类型。

Object类中toString方法的源码为:

1 public String toString() {
2     return getClass().getName() + "@" + Integer.toHexString(hashCode());
3 }

 

 1 package com.test;
 2 /**
 3  * 测试toString默认输出值
 4  * @author 林
 5  *
 6  */
 7 public class TestToString {
 8     public static void main(String[] args) {
 9         Per p=new Per();
10         System.out.println(p);        
11     }
12 }
13  
14 class Per{
15     String name;
16     int age;
17 }
执行结果:
com.test.Per@15db9742

 

 1 package com.test;
 2 /**
 3  * 测试重写toString方法
 4  * @author 林
 5  *
 6  */
 7 public class TestToString {
 8     public static void main(String[] args) {
 9         Per p=new Per();
10         p.name="林一";
11         p.age=18;
12         System.out.println(p);        
13     }
14 }
15  
16 class Per{
17     String name;
18     int age;
19     @Override
20     public String toString() {    //重写toString方法
21         return name+" "+age;
22     }
23 }

 

三、关键字

3.1、this关键字

在方法内部,可以使用一个隐含的变量this,它始终指向当前对象。因此,通过this.field就可以访问当前对象的字段。

如果没有命名冲突,可以省略this

1 class Person {
2     private String name;
3     public String getName() {
4         return name; // 相当于this.name
5     }
6 }

如果有局部变量和字段重名,那么局部变量优先级更高,就必须加上this

1 class Person {
2     private String name; 
3     public void setName(String name) {
4         this.name = name; // this不可少,this.name为成员变量
5     }
6 }

 

3.2、super关键字

 super关键字表示父类(超类)。子类引用父类的字段时,可以用super.fieldName

1 class Student extends Person {
2     public String hello() {
3         return "Hello, " + super.name;    //调用父类属性
4     }
5 }
1 class Student extends Person {
2     protected int score;
3     public Student(String name, int age, int score) {
4         super(name, age); // 调用父类的构造方法Person(String, int)
5         this.score = score;
6     }
7 }

 

3.3、static关键字

static声明的成员变量为静态属性。

static声明的方法为静态方法

  • 静态属性被该类的所有实例共享,在类被载入时被显式初始化。

  • 静态属性使用 “类名.类属性” 调用。

  • 静态方法不需要对象, 就可以调用(如:类名.方法名)。

  • 调用静态方法时, 不会将对象的引用传递给它, 所以在static方法中不可访问非static的成员。

  • 静态方法不能以任何方式引用this和super关键字。

 1 /**
 2  * 测试static关键字
 3  * @author 林
 4  *
 5  */
 6 public class TestStatic {
 7     int a;
 8     static int width;    //静态成员变量、类属性
 9     
10     static void gg() {    //静态方法
11         System.out.println("gg");
12     }
13     
14     void tt() {    //普通方法
15         System.out.println("tt");
16     }
17     
18     public static void main(String[] args) {    //java程序执行入口
19         TestStatic hi=new TestStatic();
20         TestStatic.width=2;        //调用静态成员变量
21         TestStatic.gg();   //调用静态方法
22     }    
23 }

【1】静态初始化块

  • 如果希望加载后, 对整个类进行某些初始化操作, 可以使用static初始化块。

  • 类第一次被载入时先执行static代码块; 类多次载入时, static代码块只执行一次; Static经常用来进行static变量的初始化。

  • 经常用来进行static变量的初始化。

  • 静态初始化块中不能访问非static成员。

 1 /**
 2  * 测试静态初始化块
 3  * @author 海
 4  *
 5  */
 6 public class TestStaticBlock {
 7     static { //静态初始化块,类载入时加载
 8         System.out.println("静态初始化块");
 9     }
10     
11     public static void main(String[] args) {
12         System.out.println("main方法");
13     }
14 }

 

3.4、final关键字

final作用:

  1. 修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。

  2. 修饰方法:该方法不可被子类重写。但是可以被重载。

  3. 修饰类: 修饰的类不能被继承。比如:Math、String等。

 

四、垃圾回收机制

 

五、包

包机制是Java中管理类的重要手段,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理。

【二个要点】:

  • 通常是类的第一句非注释性语句。

  • 包名:域名倒着写即可,再加上模块名,便于内部管理类。

1 package com.test;
2  
3 public class TestPerson {
4  
5 }

 

5.1、常用包

Java常用包 说明
java.lang 包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
java.awt 包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
java.net 包含执行与网络相关的操作的类。
java.io 包含能提供多种输入/输出功能的类。
java.util 包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。

 

5.2、导入类

【要点】:

  • Java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。

  • 如果导入两个同名的类,只能用包名+类名来显示调用相关类。

 1 package com.test;
 2 /**
 3  * 测试导入同名类的处理
 4  * @author 海
 5  *
 6  */
 7  
 8 import java.sql.Date;
 9 import java.util.*;
10  
11 public class Test {
12     public static void main(String[] args) {
13         Date now;
14         java.util.Date now2=new java.util.Date();    //java.util.Date和java.sql.Date类同名,需要完整路径
15         System.out.println(now2);
16         Scanner input=new Scanner(System.in);
17     }
18 }

 

5.3、静态导入

 静态导入:其作用是用于导入指定类的静态属性,这样可以直接使用静态属性。

 1 package com.test;
 2  
 3 /**
 4  * 测试静态属性导入的使用
 5  * @author 海
 6  *
 7  */
 8  
 9 import static java.lang.Math.*;        //导入Math类的所有静态属性
10 import static java.lang.Math.PI;
11  
12 public class Test {
13     public static void main(String[] args) {
14         System.out.println(PI);
15         System.out.println(random());
16     }
17 }

 

上一篇:Java开发最容易犯的几种错误


下一篇:高淇java300集JAVA面向对象的进阶作业