Java SE 面向对象(上)
面向对象的概念
Java作为一种面向对象语言,暂且不谈其特性封装,继承和多态,我们先来了解什么是类和对象,这样有助于我们接下来进一步的学习。
对象
现在让我们深入了解什么是对象。在我们真实的世界里,会发现身边有很多对象(当然不是指的男女朋友)。动物,人,汽车,房子都是我们所说的对象,而这些对象具有自己的行为和状态。
我们可以拿一只猫举个例子,猫猫就作为我们的对象,而其拥有的行为有睡觉,跑动,叫;状态就例如品种,颜色,名字,年龄等等。
那我们对比现实对象和软件对象,它们之间十分相似。软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。在软件开发中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成的。
类
类是一个模板,它描述一类对象的行为和状态。而对象是类的一个实例。我们不如创建一个猫的类来理解一下:
public class Cat {
String breed;
String colour;
String name;
int age;
void sleep(){
}
void run() {
}
void meow(){
}
}
一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
一个类可以拥有多个方法,在上面的例子中:sleep() run() meow() 都是 Cat 这个类的方法。
构造方法
每个类都有构造方法(其实就是构造了一个函数)。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
值得注意的是,构造方法没有返回值,也不能用void修饰. 如果不小心给构造方法前面添加了返回值类型,那么这将使这个构造方法变成一个普通的方法,在运行时将产生找不到构造方法的错误。
this 关键字
this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
this 的用法在 Java 中大体可以分为3种:
- 普通的直接引用:this 相当于是指向当前对象本身
- 形参与成员名字重名,用 this 来区分
- 引用构造函数:结合()使用 代表构造方法
垃圾回收
垃圾回收:用于清除垃圾对象,有JAVA虚拟机自动完成,其实本质上是在释放内存空间
可以通过System.gc()来建议进行垃圾回收
对象对回收时finalize会被调用
创建对象
对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:
- 声明:声明一个对象,包括对象名称和对象类型
- 实例化:使用关键字 new 来创建一个对象
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象
下面是一个创建对象的例子:
public class Cat{
public Cat(String name){
//这个构造器仅有一个参数:name
System.out.println("The cat name : " + name );
}
public static void main(String[] args){
// 下面的语句将创建一个Cat对象
Cat myCat = new Cat( "Bella" );
}
}
Static关键字
在java中,static是一个修饰符,用于修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能;被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问
静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途----《Java编程思想》P86.
对于static所修饰的内容,我们分为下面三类
- 修饰变量:
存储空间只有一份
通过类名直接访问 - 修饰方法:
通过类名直接访问 也可以通过实例进行访问;
不能访问实例变量和实例方法 - 修饰代码块:
类被加载的时候得到执行;应用场景 对类变量进行初始化
没有static关键字进行修饰的代码块 每创一个对象 都会得到一个执行
成员内部类和访问权限
Java 一个类中可以嵌套另外一个类,语法格式如下
class OuterClass { // 外部类
// ...
class NestedClass { // 嵌套类,或称为内部类
// ...
}
}
要访问内部类,可以通过创建外部类的对象,然后创建内部类的对象来实现。而嵌套类有两种类型:
非静态内部类
非静态内部类是一个类中嵌套着另外一个类。 它有访问外部类成员的权限, 通常被称为内部类。
由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现。
class OuterClass {
int x = 10;
class InnerClass {
int y = 5;
}
}
public class MyMainClass {
public static void main(String[] args) {
OuterClass myOuter = new OuterClass();
OuterClass.InnerClass myInner = myOuter.new InnerClass();
System.out.println(myInner.y + myOuter.x);
}
}
静态内部类
静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它
class OuterClass {
int x = 10;
static class InnerClass {
int y = 5;
}
}
public class MyMainClass {
public static void main(String[] args) {
OuterClass.InnerClass myInner = new OuterClass.InnerClass();
System.out.println(myInner.y);
}
}
注意:静态内部类无法访问外部类的成员
访问权限
所谓访问权限,指的是本类的成员变量、成员方法和内部类对其他类的可见性.
Java一共有四种访问权限,按照权限由大到小分别为public、protected、default和private,如果省略了访问修饰符,那访问权限就是defualt。访问权限的含义和权限控制如下表所示:
访问权限 | 含义 | 本类 | 本包的类 | 非本包子类 | 非本包非子类 |
---|---|---|---|---|---|
public | 公共的 | 是 | 是 | 是 | 是 |
protected | 保护访问权限 | 是 | 是 | 是 | 否 |
default | 包访问权限 | 是 | 是 | 否 | 否 |
private | 私有的 | 是 | 否 | 否 | 否 |
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public : 对所有类可见。使用对象:类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
实例运用:超市购物
public class Shopping {
public static void main(String[] args){
Product apple=new Product();
apple.setName("apple");
Product orange=new Product();
orange.setName("orange");
Product juice=new Product();
juice.setName("juice");
Market market=new Market();
market.setName("Hongqi supermarket");
market.setProducts(new Product[]{apple,orange,juice});
Person Tony=new Person();
Tony.setName("Tony");
String producename="apple";
Person Charles=new Person();
Charles.setName("Charles");
String producename2="banana";
Product product=Tony.buy(market,producename);
Product product2=Charles.buy(market, producename2);
if(product==null){
System.out.println(Tony.getName() + " didn't buy:"+ producename);
}else {
System.out.println(Tony.getName() + " buy:"+ producename);
if(product2==null){
System.out.println(Charles.getName() + " didn't buy:"+ producename2);
}else {
System.out.println(Charles.getName() + " buy:"+ producename2);
}
}
}
}
class Market {
private String name;
private Product[] products;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Product[] getProducts() {
return products;
}
public void setProducts(Product[] products) {
this.products = products;
}
public Product sell(String productName){
for(Product product:products){
if(productName.equals(product.getName())){
return product;
}
}
return null;
}
}
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Product buy(Market market,String productName){
return market.sell(productName);
}
}
class Product {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
利用上述实例来简单的理解Java的面向对象的思想,特别是对于类和对象,创建对象,构造方法的运用,以及this关键字的使用,垃圾回收来释放内存的操作。