专栏首页用代码征服天下Java基础系列1:Java面向对象

Java基础系列1:Java面向对象

该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架。

概述:

Java是面向对象的程序设计语言,Java语言提供了定义类、成员变量、方法等最基本的功能。类可被认为是一种自定义的数据类型,可以使用类来定义变量,所有使用类定义的变量都是引用变量,它们将会引用到类的对象。类用于描述客观世界里某一类对象的共同特征,而对象则是类的具体存在,Java程序使用类的构造器来创建该类的对象。

对象和类:

Java是面向对象的程序设计语言,类是面向对象的重要内容,可以把类当成一种自定义类型,可以使用类来定义变量,这种类型的变量统称为引用变量。也就是说,所有类是引用类型。对象是由类创建出来的,可以说类时对象的抽象,对象是类的实例。

对象的概念:

Java 是面向对象的编程语言,对象就是面向对象程序设计的核心。所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。对象有以下特点:

  • 对象具有属性和行为。
  • 对象具有变化的状态。
  • 对象具有唯一性。
  • 对象都是某个类别的实例。
  • 一切皆为对象,真实世界中的所有事物都可以视为对象。

面向对象与面向过程:

1、面向过程:

面向过程是一种以事件为中心的编程思想,编程的时候把解决问题的步骤分析出来,然后用函数把这些步骤实现,在一步一步的具体步骤中再按顺序调用函数。

我们以五子棋为例来解释一下面向过程是如何解决问题的:

下过五子棋的同学都知道,首先要找两个人,然后把棋谱摆放好,其中一方手持黑棋,另一方手持白旗,一般约定白棋先动,然后黑棋在动,这样每人一步,直到某一方先凑成五子一条线便为赢。这是我们平常下五子棋的过程,那么用面向过程该如何表示呢?

我们可以将下五子棋的过程抽象成如下步骤:

(1)开始游戏(2)黑子先走(3)绘制画面(4)判断输赢(5)轮到白子(6)绘制画面(7)判断输赢(8)返回步骤(2) (9)输出最后结果。

接着我们用面向过程来实现五子棋这一程序:

下五子棋{

    开始游戏();

    黑子先走();

    绘制画面();

    判断输赢();

    轮到白子();

    绘制画面();

    判断输赢();

    返回到 黑子先走();

    输出最后结果;

}

可见,面向过程始终关注的是怎么一步一步地判断棋局输赢的,通过控制代码,从而实现函数的顺序执行。

2、面向对象:

​ 一种基于面向过程的新编程思想,顾名思义就是该思想是站在对象的角度思考问题,我们把多个功能合理放到不同对象里,强调的是具备某些功能的对象。

具备某种功能的实体,称为对象。面向对象最小的程序单元是:类。面向对象更加符合常规的思维方式,稳定性好,可重用性强,易于开发大型软件产品,有良好的可维护性。

Java编程思想一书中有一段对面向对象的总结非常清晰到位,可谓是面向对象的精华所在:

1、万物皆对象 2、程序时对象的集合,它们通过发送消息来告知彼此所需要做的 3、每个对象都有自己的由其他对象所构成的存储 4、每个对象都拥有其类型 5、某一特定类型的所有对象都可以接收同样的消息

3、两者优缺点比较:

(1)、面向过程:

优点:

  流程化使得编程任务明确,在开发之前基本考虑了实现方式和最终结果,具体步骤清楚,便于节点分析。

  效率高,面向过程强调代码的短小精悍,善于结合数据结构来开发高效率的程序。

缺点:

  需要深入的思考,耗费精力,代码重用性低,扩展能力差,后期维护难度比较大。

(2)、面向对象:

优点:

  结构清晰,程序是模块化和结构化,更加符合人类的思维方式;

  易扩展,代码重用率高,可继承,可覆盖,可以设计出低耦合的系统;

  易维护,系统低耦合的特点有利于减少程序的后期维护工作量。

缺点:

  开销大,当要修改对象内部时,对象的属性不允许外部直接存取,所以要增加许多没有其他意义、只负责读或写的行为。这会为编程工作增加负担,增加运行开销,并且使程序显得臃肿。

  性能低,由于面向更高的逻辑抽象层,使得面向对象在实现的时候,不得不做出性能上面的牺牲,计算时间和空间存储大小都开销很大。

面向对象的三大特性:

概述:

1、继承:

  继承是面向对象的三大特征之一,也是实现软件复用的重要手段。Java的继承具有单继承的特点,每个子类只有一个直接父类。

2、封装:

  封装(Encapsulation)是面向对象的三大特征之一,它指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。

  封装是面向对象编程语言对客观世界的模拟,在客观世界里,对象的状态信息都被隐藏在对象内部,外界无法直接操作和修改。比如说一个人的年龄,年龄只会随着时间的流逝而逐渐增长,不能随意修改人的年龄。对一个类或对象实现良好的封装,可以实现以下目的。

3、多态:

  Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态(Polymorphism)。

  多态的作用是消除类型之间的耦合关系。

详解:

一、继承:

1、继承的概念:

程序来源于生活,也为生活所用。我们先从生活中的例子来看一下什么是继承:

现在有一个农场主,家有良田万顷,每年收入很多,他有一个儿子,就是我们口中的富二代。有一天农场主不幸去世了,那么他手下的农田和财产都是谁的了,毫无疑问,当然是他儿子的了(如果你好好努力,将来你儿子有很大机会是富二代哦)。那么他儿子本来一无所有,现在顷刻间多了需要Money,农田,房子等等,也就是拥有了他父亲的所有物资财富,这个我们就称之为继承。

Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类被称为父类,有的也称其为基类、超类。父类和子类的关系,是一种一般和特殊的关系。例如水果和苹果的关系,苹果继承了水果,苹果是水果的子类,则苹果是一种特殊的水果。

class Fruit{
	public double weight;
	public void info() {
		System.out.println("我是一个水果,重"+weight+"g");
	}
}

public class Apple extends Fruit{
	public static void main(String[] args) {
		//创建Apple对象
		Apple apple=new Apple();
		//Apple对象本身并没有weight成员变量
		//但是Apple的父类用于weight变量,所以Apple也可以方位
		apple.weight=88;
		apple.info();
	}

}

结果:我是一个水果,重88.0g

2、重写父类的方法:

子类扩展了父类,子类是一个特殊的父类。大部分时候,子类总是以父类为基础,额外增加新的成员变量和方法。但有一种情况例外:子类需要重写父类的方法。例如鸟类都包含了飞翔方法,其中鸵鸟是一种特殊的鸟类,因此鸵鸟应该是鸟的子类,因此它也将从鸟类获得飞翔方法,但这个飞翔方法明显不适合鸵鸟,为此,鸵鸟需要重写鸟类的方法。

//父类
class Bird{
	public void fly() {
		System.out.println("我在天空自由的飞翔");
	}
}

public class Ostrich extends Bird {
	//重写Bird的fly方法
	public void fly() {
		System.out.println("我只能在地上奔跑");
	}
	
	public static void main(String[] args) {
		//创建Ostrich对象
		Ostrich ostrich=new Ostrich();
		ostrich.fly();
	}
}

结果:我只能在地上奔跑

重写时需要注意:

1、返回值类型

2、方法名

3、参数类型及个数

都要与父类继承的方法相同,才叫方法的重写。

重写与重载的区别:

重写:相对继承而言,子类中对父类已经存在的方法进行区别化的修改。

重载:在同一个类中处理不同数据的多个相同方法名的多态手段。重载方法名相同,参数列表不同。

3、继承的初始化顺序:

先思考一下下面代码的输出结果:

class Animal{
	public Animal() {
		System.out.println("我是父类动物");
	}
}

class Humanity extends Animal{
	public Humanity() {
		System.out.println("我是父类人类");
	}
}

public class Student extends Humanity{
	
	public Student() {
		System.out.println("我是子类学生");
	}

	public static void main(String[] args) {
		Student student=new Student();
	}
}

不要看结果,自己先思考一下

输出结果:

1 我是父类动物
2 我是父类人类
3 我是子类学生

是不是和你思考的结果一样,不一样的同学接着往下看:

Java中继承初始化顺序如下:

1、初始化父类再初始化子类

2、先执行初始化对象中属性,再执行构造方法中的初始化。

基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是:

父类对象属性初始化---->父类对象构造方法---->子类对象属性初始化—>子类对象构造方法

下面放上一张形象的图:

4、final关键字:

final 关键字可用于修饰类、变量和方法,final关键字有点类似C#里的sealed关键字,用于表示它修饰的类、方法和变量不可改变。

final修饰变量时,表示该变量一旦获得了初始值就不可被改变,final既可以修饰成员变量(包括类变量和实例变量),也可以修饰局部变量、形参。有的书上介绍说final修饰的变量不能被赋值,这种说法是错误的!严格的说法是,final修饰的变量不可被改变,一旦获得了初始值,该final变量的值就不能被重新赋值。由于final变量获得初始值之后不能被重新赋值,因此final修饰成员变量和修饰局部变量时有一定的不同。

1、final修饰变量:

  ☆:final修饰成员变量:一旦有了初始值,就不能被重新赋值。final修饰的成员变量必须由程序显示的指定初始值。final修饰类变量必须在静态初始化块中指定初始值或声明该类变量时指定初始值,而且只能在两个地方其中之一指定;final修饰实例变量必须在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方的其中之一指定。

  ☆:final修饰局部变量:系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化。因此使用final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。

  ☆:final修饰基本类型变量与引用类型变量区别:当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。

import java.util.Arrays;

public class FinalTest {
	
	public static void main(String[] args) {
		//final修饰数组变量,arr只是一个引用变量
		final int[] arr= {3,90,33,12};
		System.out.println(Arrays.toString(arr));
		
		//对数组进行排序,合法
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr));
		//对数组元素进行赋值,合法
		arr[2]=109;
		System.out.println(Arrays.toString(arr));
		
		//下面语句对arr重新赋值,非法
		//arr=null;
		
	}

}

2、final修饰方法:

  final修饰的方法不可被重写

3、final修饰类:

  final修饰的类不可以有之类

5、this关键字:

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。

this的用法:

1、普通的直接引用

2、形参与成员名字重名,用this来区分

public class Student{
	
	String username;
	String password;
	
	public Student(String username,String password) {
		//this 代表当前对象 也就是下面的student
		this.username=username;
		this.password=password;
	}

	public static void main(String[] args) {
		Student student=new Student("jack","123");
	}
}

3、引用构造函数,这个放在super关键字中说

6、super关键字:

super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。

super的用法:

1、普通的直接引用:与this类似,super相当于是指向当前对象的父类

super.name:引用父类的变量

super.add():引用父类的方法

2、子类中的成员变量或方法与父类中的成员变量或方法同名:

class Humanity{
	public void eat() {
		System.out.println("动物吃肉");
	}
}

public class Student extends Humanity{
	
	public void eat() {
		//super调用父类中的同名方法
		super.eat();
		System.out.println("人吃饭");
	}

	public static void main(String[] args) {
		Student student=new Student();
		student.eat();
	}
}

结果:

动物吃肉
人吃饭

3、引用构造函数:

super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。

this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。

class Humanity{
	
	public Humanity() {
		System.out.println("父类无参构造");
	}
	
	public Humanity(String s) {
		System.out.println("父类有参构造======"+s);
	}
	
}

public class Student extends Humanity{
	
	public Student() {
		super();//调用父类的无参构造方法
		System.out.println("子类无参构造");
	}
	
	
	public Student(String s) {
		super(s);//调用父类的有参构造
		System.out.println("子类的有参构造======"+s);
	}
	
	public Student(String username,String password) {
		this(username);//调用本类的有参构造
		System.out.println("子类带两个参数的构造函数======"+username+"======"+password);
	}
	
	public static void main(String[] args) {
		Student student=new Student();
		Student student2=new Student("小明");
		Student student3=new Student("小明","123");
	}
	
}

输出结果:

父类无参构造
子类无参构造
父类有参构造======小明
子类的有参构造======小明
父类有参构造======小明
子类的有参构造======小明
子类带两个参数的构造函数======小明======123

二、封装:

未完待续...

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java——Java面向对象

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形...

    说故事的五公子
  • java之Lambda表达式

    上面的一段代码和之前的除了参数传递方式不同,其他都一样,第一段代码用匿名内部类的方式实现参数传递,第二段代码用Lambda表达式实现参数传递。

    说故事的五公子
  • 各种递归算法

    说故事的五公子
  • Java——Java面向对象

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形...

    说故事的五公子
  • 快速梳理23种常用的设计模式

    本文旨在快速梳理常用的设计模式,了解每个模式主要针对的是哪些情况以及其基础特征,每个模式前都有列举出一个或多个可以深入阅读的参考网页,以供读者详细了解其实现。

    后端技术漫谈
  • 简单笔记

    1、类的表面类型和实际类型 实例对象有两个类型:表面类型(Apparent Type)和实际类型(ActualType),表面类型是声明时的类型,实际类型是对象...

    陈树义
  • Java:类与继承

    对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础。抽象、封装、继承、多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解...

    Java团长
  • 【java】java反射初探 ——“当类也学会照镜子”

    反射的作用 开门见山地说说反射的作用 1.为我们提供了全面的分析类信息的能力 2.动态加载类 我理解的“反射”的意义 (仅个人理解哈) 我理解的java反射机制...

    外婆的彭湖湾
  • Java:类与继承

      对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础。抽象、封装、继承、多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来...

    Java团长
  • Java反射初探 ——“当类也学会照镜子”

    镜子(反射机制)照出(反射)了人的全貌(类的全方位的信息,例如方法,成员变量和构造器等的相关信息)

    Java团长

扫码关注云+社区

领取腾讯云代金券