1、面向对象
面向对象的优点:
(1)便于程序模拟现实世界中的实体
用“类”表示实体的特征和行为
(2)隐藏细节
对象的行为和属性被封装在类中,外界通过调用类的方法来获得,不需关注内部细节如何实现
(3)可重用
可以通过类的模板,创建多个类的对象
2、对象
(1)特征:
属性:attribute / field / property
属性是对象具有的各种特征。
每个对象的每个属性都拥有特定值。
方法 / 行为:method
方法是对象执行的操作。
(2)使用对象的步骤:
使用new创建一个对象:
School center = new School();
使用对象:
center.schoolName = “qinghua"; 对象名.属性
center. toInter (); 对象名.方法名()
(3)对象在内存中的存放形式
3、类
类是具有相同属性和方法的对象的集合。
所有Java程序都以类class为组织单元。
定义一个类的步骤:
- 定义类名
- 编写类的属性
- 编写类的方法
4、类和对象的区别
类是抽象的概念,仅仅是模板,比如说:“人”。
对象是一个你能够看得到、摸得着的具体实体,比如:“张三”。
5、抽象
把相同的或相似的对象归为一类的这个过程就是抽象,所以,抽象就是分析问题的方法。
抽象的过程其实就是面向对象编程的核心思想之一。
6、成员运算符:.
在Java中,只有先实例化类的对象,才可以访问到类中的成员(属性和方法)。
使用成员运算符(.)来访问成员属性或成员方法;
一般语法是:
对象名.成员名
std.age = 18; //为成员属性赋值
std.dining(); //调用成员方法
7、构造器 / 构造方法:constructor
在上例中,只能逐个地为数据成员赋值,如果想在对象实例化的同时就初始化成员属性,就使用到了构造方法。正是由于在实例化对象的同时会自动调用构造方法,所以构造方法一般用来给数据成员分配资源或初始化数据成员。
作用:对象实例化。
构造方法是特殊的成员方法,它与类同名,在对象实例化时由虚拟机自动调用。因为是由虚拟机来调用构造方法,所以构造方法一般应定义成public。
只有调用构造方法,才能在内存中开辟空间,才允许存放类中属性和方法的数据。
构造方法的一般形式:
访问权限 类名(形参列表) {
方法体
}
请注意:
- 构造方法没有返回值类型,也不能有返回值。
- 构造方法一般定义成public
- 每个对象在生成时都必须执行构造方法,而且只能执行一次。
- 如果构造方法调用失败,那么对象也无法创建。
- 不可以显式地直接调用构造方法。
- 在没有定义构造方法的情况下,类会自动产生一个无参数的默认构造方法,这个默认的构造方法什么都不做。
一旦显式地定义了构造方法,默认构造方法自动消失。
例:
Person.java:
public class Person {
String name;
// 无参构造器
public Person() {
System.out.println("又一个人诞生了!");
}
// 含参构造器
public Person(String name) {
this.name = name;
System.out.println
("一个人诞生了,他的名字是:"+this.name);
}
}
TestConstructor.java:
public class TestConstructor {
public static void main(String[] args) {
// 通过Person类的含参构造器实例化一个对象person
Person person = new Person("张三");
person.name="李四";
System.out.println("名字:"+person.name);
// 通过Person类的无参构造器实例化一个对象p1
Person p1 = new Person();
p1.name="王五";
System.out.println("人名字:"+p1.name);
}
}
8、this关键字
既然所有的对象都共用相同的成员方法,那么在不同的对象都调用同一方法时,它是怎么确定要使用哪个对象的数据成员呢?
每个成员方法都有一个隐含的this引用,它总是指向调用它的对象;
关键字this给出用于调用成员方法的对象的地址;
每当调用成员方法时,编译器会向this分配调用该方法的对象的地址;
可以像使用任何引用那样使用this。
/*this示例,代码片段*/
public class Student //定义学生类
{
private String mName; //姓名
private int mAge; //年龄
public Student(String name, int age)
{
//隐式调用,等同于this.mName = name;
mName = name;
//显式调用,等同于mAge = age;
this.mAge = age;
}
……
}
注意:在static作用域内,绝对不可以使用this关键字!!!
(因为this是指向本类的一个实例,而static只有一个实例)
9、面向对象的3大基本特征:
(1)封装
(2)继承
(3)多态
10、堆区、栈区、方法区
Java的内存分为3个区:堆(heap)、栈(stack)、方法区(method)。
堆区:
存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)。
JVM只有一个堆区被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。
栈区:
每个线程包含一个栈区,栈中只保存基本数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中。
每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
String say(String name){return "abc"}
// name、"abc"等都存放在方法区
11、静态成员
(1)变量
Java中的变量可分为成员变量和局部变量。
两种变量的作用域和加载时间均不一样。
(2)静态成员变量
在成员变量前加static关键字,可以将其声明为静态成员变量;
如果类中成员变量被定义为静态,那么不论有多少个对象,静态成员变量只有一份内存拷贝,即所有对象共享该成员变量;
在没有实例化对象时,可以通过类名访问静态成员变量;也可以通过对象访问静态成员变量,但不论使用的是哪个对象,访问到的都是同一个变量。
静态成员变量的作用域只在类内部,但其生命周期却贯穿整个程序。和程序同生命周期。
静态成员变量在声明时最好初始化,如果不进行初始化,系统会默认初始化为0。
package test;
class Dog{
public static int count = 0; //静态成员变量
public Dog() { //构造方法
count++;
}
}
public class Test{
public static void main(String[] args){
System.out.println("当前狗的数量是:" + Dog.count);
Dog d1 = new Dog();
Dog d2 = new Dog();
System.out.println("当前狗的数量是:" + Dog.count);
}
}
(3)静态成员方法
在成员方法前加static关键字,可以将其声明为静态成员方法;
静态成员方法只能对类的静态成员变量(静态属性和静态方法)进行操作,不能操作非静态成员变量。(因为static属性和方法是在编译(javac)时开辟的内存空间,而普通变量和方法是在运行(java)时才产生)
静态成员方法没有this引用;
在没有实例化对象时,可以通过类名访问静态成员方法。
package test;
class Dog {
private static int count = 0; //静态成员变量
public Dog() {
count++;
}
//显示数量的方法,静态成员方法
public static void displayCount() {
System.out.println("当前狗的数量是:" + count);
}
}
public class Test {
public static void main(String[] args) {
//没有实例化对象之前,直接通过类名调用静态成员方法
Dog.displayCount();
Dog d1 = new Dog();
Dog d2 = new Dog();
Dog.displayCount();
}
}
12、包
有时候,类和类的名称可能发生冲突;Java提供了把类名空间划分为更容易管理的块的机制,这就是包;包允许将类组合成较小的单元,类似于文件夹。
- 有助于避免命名冲突,分属不同包的类即便名称相同也不会引起误会。
- 能在包与包之间对于类的访问权限提供更有力的约束。
(1)缺省包
如果省略了package语句,类将保存在一个缺省的没有名称的包中;
尽管缺省包很方便,但对于大型的程序,它是不恰当的;
请尽量为自己编写的类定义具体的包。
(2)使用package关键字打包
可以使用package关键字将源文件中的类打入某个包中,语法是:
package 包名;
该语句必须是整个源文件的第一条语句。
package mypkg; //将本源文件中的所有类打到mypkg包中
class Student { //定义学生类
……
}
(3)使用import关键字导入包
如要使用到某个包中的类,就需要使用import关键字将包或类显式地包括到程序中。有如下两种情况:
/*导入java包下的io子包中的所有类*/
import java.io.*;
/*导入mypkg包下的Student类,但并不导入该包中的其它类*/
import mypkg.Student;
……
一个程序中允许有多条import语句,导入多个包或多个类。