《 高淇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()); // 打印1510 }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),是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。
【构造方法要点】:
通过new关键字调用。
构造方法有返回值,但不能定义返回值类型,不能在构造器里使用return返回某个值。
如没有定义构造方法,则编译器会自动定义一个无参的构造方法。如已定义则编译器不会自动添加。
构造器的方法名必须和类名一致。
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); //false14 System.out.println(p1.equals(p2)); //false15 16 String s1=new String();17 String s2=new String();18 System.out.println(s1==s2); //false19 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 @Override20 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.name5 }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作用:
修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。
修饰方法:该方法不可被子类重写。但是可以被重载。
修饰类: 修饰的类不能被继承。比如: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 }