要理解面向对象思想,我们先要知道什么是对象?
《Java编程思想》中提到“万物皆为对象”的概念。它将对象视为一种奇特的变量,它除了可以存储数据之外还可以对它自身进行操作。它能够直接反映现实生活中的事物,例如人、车、小鸟等,将其表示为程序中的对象。每个对象都具有各自的状态特征(也可以称为属性)及行为特征(方法),java就是通过对象之间行为的交互来解决问题的。
面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。
类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。
类具有三个特性:封装、继承和多态。
封装:核心思想就是“隐藏细节”、“数据安全”,将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。所有的内容对外部不可见。
继承:子类可以继承父类的属性和方法,并对其进行拓展。将其他的功能继承下来继续发展 。
多态:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以及方法的重写和重载可以实现多态。方法的重载本身就是一个多态性的体现。
三大思想
面向对象思想从概念上讲分为以下三种:OOA、OOD、OOP
OOA:面向对象分析(Object Oriented Analysis)
OOD:面向对象设计(Object Oriented Design)
OOP:面向对象程序(Object Oriented Programming )
类与对象
类表示一个共性的产物,是一个综合的特征,而对象,是一个个性的产物,是一个个体的特征。 (类似生活中的图纸与实物的概念。)
类必须通过对象才可以使用,对象的所有操作都在类中定义。
类由属性和方法组成:
属性:就相当于人的一个个的特征
方法:就相当于人的一个个的行为,例如:说话、吃饭、唱歌、睡觉
一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
类名称 对象名称 = new 类名称() ;
如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:
访问类中的属性: 对象.属性 ;
调用类中的方法: 对象.方法(实际参数列表) ;
类必须编写在.java文件中;
一个.java文件中,可以存在N个类,但是只能存在一个public修饰的类;
.java文件的文件名必须与public修饰的类名完全一直;
同一个包中不能有重名的类;
匿名对象:没有对象名称的对象就是匿名对象。 即栈内存中没有名字,而堆内存中有对象。只使用一次的对象可以通过匿名对象的方式完成
内部类
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
广泛意义上的内部类一般来说包括这四种:
1、成员内部类
2、局部内部类
3、匿名内部类
4、静态内部类
成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
public class Demo{
public static void main(String[] args){
//外部使用成员内部类
Outer outter = new Outer(100);
Outer.Inner inner = outter.new Inner();
inner.say(); //输出:200
// 100
}
}
class Outer {
private double x = 0;
public Outer(double x) {
this.x = x;
}
class Inner {
private double x=200;
//内部类
public void say() {
System.out.println(x);
System.out.println(Outer.this.x);
}
}
}
特点: 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。 不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。
如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
匿名内部类
匿名内部类由于没有名字,所以它的创建方式有点儿奇怪。匿名内部类创建出来只能使用一次,和匿名对象类似。
静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。
基本数据类型和包装类型的区别
1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是
2、包装类型是引用的传递,基本类型是值的传递
3、声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间
4、存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们
5、初始值不同,eg: int的初始值为 0 、 boolean的初始值为false 而包装类型的初始值为null
6、使用方式不同,基本数据类型直接赋值使用就好 ,而包装类型是在集合如 coolection Map时会使用
抽象类
抽象类必须使用abstract class声明
一个抽象类中可以没有抽象方法。抽象方法必须写在抽象类或者接口中。
// 抽象类
abstract class 类名{
public abstract void 方法名() ; // 抽象方法,只声明而未实现
}
1、 抽象类能否使用final声明?
不能,因为final属修饰的类是不能有子类的 , 而抽象类必须有子类才有意义,所以不能。
2、 抽象类能否有构造方法?
能有构造方法,而且子类对象实例化的时候的流程与普通类的继承是一样的,都是要先调用父类中的构造方法(默认是无参的),之后再调用子类自己的构造方法。
抽象类和普通类的区别
1、抽象类必须用public或protected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。 默认缺省为 public ;
2、抽象类不可以使用new关键字创建对象, 但是在子类创建对象时, 抽象父类也会被JVM实例化 ;
3、如果一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必须定义为 abstract类 ;
多态
多态:就是对象的多种表现形式,(多种体现形态)
多态的体现
对象的多态性,从概念上非常好理解,在类中有子类和父类之分,子类就是父类的一种形态 ,对象多态性就从此而来。
ps: 方法的重载 和 重写 也是多态的一种, 不过是方法的多态(相同方法名的多种形态)。
重载: 一个类中方法的多态性体现 。
重写: 子父类中方法的多态性体现。
多态的使用:对象的类型转换
类似于基本数据类型的转换:
向上转型:将子类实例变为父类实例 |- 格式:父类 父类对象 = 子类实例 ;
向下转型:将父类实例变为子类实例 |- 格式:子类 子类对象 = (子类)父类实例 ;
public class Demo{
public static void main(String[] args){
Student student1=new Student();
Nurse nurse1=new Nurse();
//向上转型,父类引用指向子类对象
Person person1=student1;
person1.say(); //输出:我是学生
Person person2=nurse1;
person2.say(); //输出:我是护士
//向下转型
Student student2=(Student)person1;
student2.say(); //输出:我是学生
//向下转型需要注意的是不能把原来是护士的张三转成学生 例如:
Student student3=(Student)person2;
student3.say(); //此处会报错
//向上转型比较高级的用法
Student student4=new Student();
say(student4); //输出:我是学生
}
public static void say(Person person){
person.say();
}
}
abstract class Person{
public abstract void say();
}
class Student extends Person{
@Override
public void say(){
System.out.println("我是学生");
}
}
class Nurse extends Person{
@Override
public void say(){
System.out.println("我是护士")
}
}