浅谈Java面向对象

写在前面:⾯向过程面向对象编程缺少了可重⽤性设计。

⾯向对象三⼤特征

一. 封装性:所谓封装,也就是把客观事物封装成抽象的类,并且类可以把⾃⼰的数据和⽅法只让可信的类或者对象操作,对不可信的进⾏信息隐藏。简⽽⾔之就是,内部操作对外部⽽⾔不可⻅(保护性)。
二. 继承性:继承是指这样⼀种能⼒:它可以使⽤现有类的所有功能,并在⽆需重新编写原来的类的情况下对这些功能进⾏扩展。
三 . 多态性:所谓多态就是指⼀个类实例的相同⽅法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接⼝。(利⽤多态可以得到良好的设计)

类与对象的定义与使⽤

1. 类的概念:所谓的类就是指共性的概念,⽽对象指的是⼀个具体的、可以使⽤的事物。

2. 类的定义如下:

class 类名称 {
 属性1;
 属性2;
 属性n...;
 
 ⽅法1(){}
 ⽅法2(){}
 ⽅法n(){}...
}

代码示例:

class Car{
 String style;
 int price;
 
 public Car(String style,int price){
 this.style = style ;
 this.price = price ; 
 }
 
 public String getCarInfo(){
 return "款式:"+this.style+",价格:"+this.price;
 }
}

由上面的定义可以看出,类由属性和方法组成。
属性:变量,描述每个对象的具体特点;
⽅法:操作的⾏为。

3. 由类产生对象:

语法如下:

类名称 对象名称 = new 类名称();

以上述Car类为例,产生如下一个Car类的对象(实例):

Car c = new Car();
Car c2 = new Car("Camaro",400000);  //产生了一个“科迈罗”跑车,它的价格为400000

通过关键字 new,开辟了内存。

4. 对象内存分析:
首先我们先简单的理解Java中的内存区域为栈内存堆内存两个区域。(实际很复杂)

栈内存(虚拟机局部变量表):存放的是局部变量。(包含编译期可知的各种基本数据类型、对象引⽤-即堆内存的地址,可以简单的理解为对象的名称)
堆内存:保存的是真正的数据即对象的属性。

通过上述的Car类,我们来分析一下内存中是怎么分配的:

首先:

Car c = new Car();

在这里插入图片描述
通过图片我们可以发现,对象实例保存在栈内存上,而属性和方法在堆内存上,上述代码只是通过new开辟了内存空间,并没有赋值,可以通过引用的方式为属性赋值,如下:

Car.name = "camaro";
Car.price = 400000;

在这里插入图片描述
如果此时再new一个Car类的对象c2,并让c2 = c,在内存上会发生什么呢?

在这里插入图片描述
我们可以看到,让c2 = c只会发生引用传递,即让两个对象指向同一个堆内存空间,而使得c2的堆内存成为垃圾内存空间。所以在以后的开发过程中,尽量控制好对象的产生数量,不产生无用的对象。

类的封装

用private关键字实现对类的封装,让内部操作对外部不可⻅。(对象不能直接操作属性)private实现封装的最⼤特征在于:只允许本类访问,⽽不允许外部类访。
问。

例如:

private String style;
private int price;

这样就对款式和价格这两个属性进行了封装,成为了私有属性

如果要实现对私有属性的访问,有以下两种方法可以使用:
1.提供一系列的 setter() 和 getter() 方法;

     public void setStyle(String s){
     		style = s ;
     }
     public String getStyle(){
    		 return style;
     }


	 public void setPrice(int p){
     		price= p;
     }
     public String getPrice(){
    		 return price;
     }

2.提供合适的构造方法。

public Car(String style,int price){
 		this.style = style ;
		 this.price = price ; 
 }

注意:我们在编写类时,类中的所有属性必须使⽤private封装。

上面提到了构造方法,那么构造方法有什么特点呢?

  1. ⽅法名称必须与类名称相同;
  2. 构造⽅法没有返回值类型声明;
  3. 每⼀个类中⼀定⾄少存在⼀个构造⽅法。(没有明确定义,则系统⾃动⽣成⼀个⽆参构造)
    使用用构造方法初始化对象的属性进行初始化可以避免多次setter调⽤。
    构造方法还可以进行重载,在于其参数的个数不同。有若干构造方法时,为了良好的代码风格,按照参数个数升序或者降序排列。

继承

继承的出现提高了代码的重用性。
继承的实现语法如下:

class ⼦类 extends ⽗类

子类被称为派生类,父类被称为超类。

继承的东西:继承了除了构造函数之外的其他的东西。

Java中只允许单继承,不允许多继承,但是可以多层继承。

在使用javap -c反汇编的时候我们会看到一些专有名词:

  • invokespecial 代表构造函数
  • invokevirtual 普通的方法 虚函数
  • invokestatic 静态方法

重载(overload )和重写(override )

  • overload 重载:函数名相同,参数列表不同,返回值不要求;
  • override 重写:函数名相同,参数列表相同,返回值相同。

this和super关键字

这两个关键字有着很相似的地方,它们都可以访问属性、方法,但是也有本质上的区别,下面通过一张表给大家区分一下:

在这里插入图片描述
需要说明的一点,在使用this调用本类普通方法时,可以省掉this,但是加上可以更好地区分方法的定义来源。this和super调用构造方法时,必须放在构造方法的首行。

static关键字

static可以用来修饰属性和方法。

  • 通过static修饰的属性称为类属性,保存在全局数据区内存中,所有对象都可以进行该数据区的访问。而普通属性保存在堆内存中,且每个对象独享属性。

  • 访问static属性应该用类名称.属性名

  • 所有的⾮static属性(实例变量)必须在对象实例化后使⽤,⽽static属性(类属性)不受对象实例化控制

  • 使⽤static定义的⽅法,直接通过类名称访问

  • 所有的static⽅法不允许调⽤⾮static定义的属性或⽅法

  • 所有的⾮static⽅法允许访问static⽅法或属性

final关键字

  • 使⽤final修饰类、⽅法、属性
  • final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误
  • 使⽤final定义的类不能有⼦类
  • final⼀旦修饰⼀个类之后,该类的所有⽅法默认都会加上final修饰。(不包含成员变量)
  • 使⽤final定义的⽅法不能被⼦类所覆写
  • 使⽤final定义的变量就成为了常量,常量必须在声明时赋值,并且不能够被修改
  • 使⽤final修饰的变量不能再次赋值
  • 定义常量(public static final ),常量全⽤⼤写字⺟,多个单词间以_分隔。

代码块

根据代码块定义的位置和关键字分为普通代码块、构造块和静态块。
1.普通代码块:

{
	...			//直接使用{}定义
	...
}

2.构造块:

class A{
{
	...//定义在类中的代码块(不加修饰符)
}
}

3.静态代码块:

static{
	...  
}

注意:

  • 构造块优先于构造⽅法执⾏,每产⽣⼀个新的对象就调⽤⼀次构造块,构造块 可以进⾏简单的逻辑操作(在调⽤构造⽅法前)
  • 静态块优先于构造块执⾏
  • ⽆论产⽣多少实例化对象,静态块都只执⾏⼀次
  • 在主类中定义的静态块,优先于主⽅法(main)执⾏

内部类

内部类分为4种,分别是成员内部类(本地内部类)、静态内部类、方法内部类(局部内部类)、匿名内部类。

使用内部类创建内部类对象的语法:

外部类.内部类 内部类对象 = new 外部类().new 内部类();
 Outter.Inner in = new Outter().new Inner();

在外部类内部创建内部类对象:

内部类 内部类对象 = new 内部类();
Inner in = new Inner();

内部类的特点:

  • 内部类⽅法可以访问该类定义所在作⽤域中的数据,包括被 private 修饰的私有数据
  • 内部类可以对同⼀包中的其他类隐藏起来
  • 内部类可以实现 java 单继承的缺陷
  • 对于⾮静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是⽆法创建内部类的
  • 内部类是⼀个相对独⽴的实体,与外部类不是is-a关系
  • 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类的元素
  • 外部类可以通过内部类引⽤间接访问内部类元素
  • 成员内部类中不能存在任何static的变量和⽅法
  • 静态内部类不可以使⽤任何外围类的⾮static成员变量和⽅法
  • 局部内类不允许使⽤访问权限修饰符 public private protected 均不允许
  • 匿名内部类是没有访问修饰符的,不能存在任何静态成员或⽅法,也没有构造方法

多态

  • 对象多态性的核⼼在于⽅法的覆写。
  • 通过对象的向上转型可以实现接收参数的统⼀,向下转型可以实现⼦类扩充⽅法的调⽤(⼀般不操作向下转型,有安全隐患)。
  • 两个没有关系的类对象是不能够进⾏转型的,⼀定会产⽣ClassCastException。
  • 静多态: 调用静态函数。
  • 动多态: 运行时多态。

猜你喜欢

转载自blog.csdn.net/wener521/article/details/89099237