今天的博客主题
基础篇 –》面向对象 –》Java类、Java对象
面向对象
面向过程、面向对象
面向过程就是做一件事的时候,每一个步骤都是紧密相连的,任何一环出了问题,那么任务失败
比如 蛋炒饭,每一步都是紧密相关连的
特点:高内聚
面向对象就是做一件事的时候,把这个事拆分成几个不同的部分,每一部分都是独立的,任何一部分出了问题,跟其他部分无关
比如 xxx盖饭,xxx和盖饭是分开的。
特点:低耦合
Java是面向对象的高级编程语言,类和对象是Java程序的构成核心。
Java类和Java对象,有三大基本特性:
- 封装是 Java 类的编写规范
- 继承是类与类之间联系的一种形式
- 多态为系统组件或模块之间解耦提供了解决方案
Java 是完全面向对象编程语言,所以必须熟悉面向对象才能够编写 Java 程序。
面向对象的程序核心是由对象组成的,每个对象包含着对用户公开的特定功能和隐藏的实现部分。
程序中的很多对象来自 JDK 标准库,而更多的类需要我们自定义。
从理论上讲,只要对象能够实现业务功能,其具体的实现细节不必特别关心。
面向对象有以下特点:
- 面向对象是一种常见的思想,比较符合人们的思考习惯;
- 面向对象可以将复杂的业务逻辑简单化,增强代码复用性;
- 面向对象具有抽象、封装、继承、多态等特性。
面向对象的编程语言主要有:C++、Java、C#等。
Java作为一种面向对象的语言,支持以下多种概念:
- 封装
- 继承
- 多态
- 抽象
- 接口
- 实现
- 类
- 对象
- 重载
这篇就说一下类和对象。
什么是类?
在生活当中比如猫狗鸡鸭鹅被称为动物类。花草树木被称为植物类。
在Java当中,把抽取同类实体的共同性定义一种数据类型被称之为类。
是具备某些共同特征的实体集合,是一种抽象数据类型。
在面向对象的程序设计语言中,类是对一类事物的属性和行为的抽象。
类可以看做是一个模板,描述一类对象的行为及状态。
比如:人类
人类状态有:姓名、性别、年龄、等这些就是属于状态。
人类行为有:吃饭、睡觉、工作等这些就是属于人类的行为
怎样定义一个类?
在Java里使用Class关键字来定义一个类。
举例说明:定义一个Person类
public class Person {
private String name;
private String sex;
private int age;
public void toStr(){}
}
说明:类名首字母要大写,如果有多个单词组成那就每个单词的首字母大写
一般都会用public关键字来修饰,作为一个公开类。
在上面的Person类里面,name、sex、age都成为类属性,数据成员或字段。
toStr()成为类的成员函数或方法。
类的组成
- 一个类由方法和变量(属性)组成
- 变量又分为成员变量和局部变量
- 成员变量:直接写在类的下面
- 局部变量:写在方法里或者方法的参数里
什么是对象?
在生活当中,万事万物皆为对象。
对象是类的一个个体,是具体的,实实在在存在的事物,它有自己的生命周期,由类可以创建出对象,对象也会消亡。
类一旦被建立后,就可以用这个类创建出任意个对象,然后去操作这些对象,类是抽象的,对象是具体的。
类和对象的关系
如果把对象看做一个实实在在的房子,那设计这个房子的图纸就是类,可以通过这个图纸建造N个这样的房子(那N个这样的房子就都是对象)
通过上边的Person类可以创建一个叫“张三”的对象,也可以创建一个叫“李四”的对象。
怎样创建一个对象?
对象是根据类来创建的,通过new关键字来创建一个新的对象。创建一个对象需要3步。
- 声明:声明一个对象,对象类型 对象名称。
- 实例化:通过new 关键字。
- 初始化:调用构造方法初始化对象。
声明:Person zhangsan(对象类型 对象名称)
实例化:new(new关键字)
初始化:Person() (调用构造方法 )
合起来 Person zhangsan = new Person();
这样就创建了一个叫做“张三”的对象(在实际当中避免这种命名,要遵循Java命名规范),实例化了一个类。
创建这个对象的过程也叫做这个类的实例化。
对象是如何引用的又是如何分配的?
例:
// Person类
public class Person {
private String name;
private String sex;
private int age;
public void toStr(){
System.out.println("我是Person类对象的方法");
}
}
// TestDemo 类
public class TestDemo {
int i = 10;
int j = 20;
static int k = 30;
public static void main(String[] args) {
//创建了person对象,实例化了Person类
Person person = new Person();
//调用Person类里的toStr()方法
person.toStr();
}
}
在上例代码中Person类在TestDemo类里面的main方法中被创建了。
Person person = new Person();这段代码就是对象创建过程(类实例化过程)
Person person 声明对象的引用变量,这个变量是在栈(stack)内存中分配的,它存储着一个内存地址,该地址指向执行new Person()后在堆中分配的一块内存。
new Person() 创建一个对象,该对象是在堆(heap)内存中动态分配的。
如下图:
说明:
new出来的对象都是在堆(heap)中分配的
局部变量(如对象引用变量)都是在栈(stack)中分配
静态变量(被static修饰的变量)和字符串常量存储在数据段(Data Segtment)中
代码段(Code Segment)中存放代码
堆栈的详细讲JVM的时候会重点讲解,先知道堆栈是JVM里面的。
引用变量和方法(访问变量和方法)
//实例化对象
Person person = new Person();
//访问类中方法
person.toStr();
//访问类中变量
person.asd;
例:
// Person 类
public class Person {
public String name;
public String sex;
public int age;
public Person(String name){
System.out.println("姓名:" + name);
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// TestDemo 类
public class TestDemo {
public static void main(String[] args) {
//创建对象,调用构造方法
Person person = new Person("张三");
//通过set方法来设置参数
person.setSex("男");
person.setAge(18);
//通过get方法获得参数
System.out.println("性别:" + person.getSex());
System.out.println("年龄:" + person.getAge());
//创建对象,调用构造方法
Person person2 = new Person("李四");
//通过set方法来设置参数
person2.setSex("男");
person2.setAge(21);
//直接访问属性
System.out.println("性别:" + person2.sex);
System.out.println("年龄:" + person2.age);
}
}
输出结果:
姓名:张三
性别:男
年龄:18
姓名:李四
性别:男
年龄:21
通过上例代码我们发现在Person类中,出现了getXxx()、setXxx(),那么这个是什么呢?这个被称为get set方法,什么意思呢?有什么作用呢?
从字面意思上理解,get就是取,set就是设置。顾名思义那么这两个方法就是对数据进行设置和获取的。
在类中使用get set方法时,后面都会跟上特定的词来形成特定意思的方法名,比如setSex()和getSex()那就是设置性别和获取性别的。
一般在Person类中,定义的属性都要用private关键字来修饰,不要用public来修饰,这就涉及到了Java面向对象编程中的封闭性和安全性。
封闭性也就是对类中的成员变量进行封闭操作,也就是用private关键字来修饰他们,这样其他类则不能对类中变量访问。这样我们就将这些变量封闭在了类内部,这样就提高了数据的安全性。
那想要操作这些成员变量怎么办呢?我们可以通过两种方法,第一中即通过public方式的构造器(构造函数),对象一实例化就对该变量赋值。第二种就是通过上面提到的set和get方法。
用到get set方法之后,就不用直接对Person类中的域变量操作,而是通过set get方法间接地操作这些变量,这样就能提高域变量的安全性,同时又保证了域变量的封装型。
不仅如此,有了get set方法,可以对数据做很多操作。
(1)只有属性才可以数据绑定,字段不可以
(2)可以添加日志、校验等逻辑,可以拦截字段的修改
(3)可以实现懒惰数据加载提高性能
(4)可以通过多个属性修改一个字段,或者将一个字段的数据通过几个属性表现出来
(比如位置是一个Point对象,但是你可以将它拆成x y两个属性,比如字体是一个字段,你可以拆出字体、字号等属性,再比如用二进制掩码表示一系列bool值,等等)
(5)可以代替方法。比如说Timer的Start Stop两个方法,被封装成Enabled属性
(6)可以为读写设置不同的访问级别,可以创建只读的属性
内部类
一个类被定义到了另一个类的里面或者方法里面这个类就叫做内部类
内部类包括成员内部类、局部内部类、匿名内部类和静态内部类四种
成员内部类
成员内部类在外部类的成员位置,成员内部类可以无条件访问外部类的所有内容包括static静态的和private私有的。
当内部类定义了和外部类相同的成员变量和方法时,就近原则优先访问内部类的变量和方法,如果需要使用外部类的成员和方法需要使用this关键字。
外部类不能直接访问内部类的变量和方法,需要通过创建内部类的对象来访问:
例
public class TestDemo{
int i = 10;
private int ii = 20;
class testDemoOne{
public void show(){
System.out.println(i);
System.out.println(ii);
}
}
}
成员内部类是依附于外部类而存在的,也就是说如果想要创建一个内部类的对象前提需要有一个外部类的对象,其他类中需要访问成员内部类的方法或者变量需要通过:
外部类名.内部类名 对象名 = 外部类对象.内部类对象
来创建成员内部类的对象
public class TestDemo{
int i = 10;
private int ii = 20;
class testDemoOne{
public void show(){
System.out.println(i);
System.out.println(ii);
}
}
}
public class HelloWorld2 {
public static void main(String[] args) {
TestDemo.testDemoOne tt = new TestDemo().new testDemoOne();
tt.show();
}
}
输出结果
10
20
如果成员内部类的访问权限是private,那么这个内部类只能在外部类中访问,其他类中不能通过上面的方法来创建私有内部类的对象。
局部内部类
局部内部类是定义在一个方法里的类,局部内部类的访问仅限于方法内或者该作用域内。
局部内部类访问局部变量时候需要给局部变量添加final
因为局部变量是在方法中定义的变量,当当前方法执行完毕后局部变量会被Java回收,
此时如果局部内部类的对象对局部变量还存在引用的话就会出现对象指向了一个不存在的变量,因此局部内部类只能访问被final修饰的局部变量。
局部内部类是不能有public,private,static这样的修饰词的
例
public class TestDemo{
public void show(){
class TestDemo2{
final int anInt = 1;
public void show2(){
System.out.println(anInt);//局部内部类访问局部变量时候需要给局部变量添加final
}
}
}
}
静态内部类
静态内部类就是成员内部类前面加了static,他的特点是只能访问外部类中被static修饰的成员
例
public class TestDemo{
static int anInt = 10;
static class TestDemo2 {
public void show() {
System.out.println(anInt); // 只能访问外部的静态成员
}
}
}
public static void main(String[] args) {
TestDemo.TestDemo2 tt = new TestDemo.TestDemo2(); // 静态内部类创建对象的方式
tt.show();
}
输出结果
10
匿名内部类
匿名内部类在实际开发中用的最多,匿名内部类的前提条件是存在一个类或者接口,这个类可以为抽象类。
匿名内部类的格式为
new 类名或接口名{
重写方法;
}
匿名内部类本质上是继承了该类或实现了接口中的方法
例
public class TestDemo{
public static void main(String[] args) {
new HelloWorld() {
@Override
public void getHello() {
System.out.println("你好啊");
}
};
}
}
问题总结:
一、给成员变量赋值有几种方式?
1、通过set/get方法
2、通过带参构造器
多动手,多思考