面向对象是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,同时了解这些对象具有哪些相应的属性以及展示这些对象的行为。
对象是事物存在的实体。
对象分为两个部分:静态部分和动态部分
静态部分: 不能动的部分,此部分被称为属性,任何对象都会具备其自身属性。如人的属性包括性别、高矮、胖瘦等。
动态部分: 执行的动作。如人的跑、跳、行走等。行为大多是对象基于属性而具有的动作。
类就是同一类事物的统称。 如鸟类、人类。
对象与类的关系:
类就是对象的设计图。
类是世间事物的抽象称呼,而对象是这个事物相对应的实体。
面临实际问题,通常需要实例化类对象来解决。
类是封装对象的属性和行为的载体:具有相同属性和行为的一类实体成为类。
Java中,类中对象的行为是以方法的形式定义的,对象的属性是以成员的变量的形式定义的,所以类包括对象的属性和方法。
-封装性
-继承性
-多态性
封装是面向对象编程的核心思想。 将对象的属性和行为等装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。
例如,使用计算机时敲击键盘就可以实现功能,用户无需知道内部工作的原理。
应用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据。避免了外部操作对内部数据的影响,提高了程序的可维护性。
类与类之间具有关系,这种关系称为关联。 关联主要描述两个类之间的一般二元关系。
继承是关联中的一种。
处理问题时,可以将一些有用的类保留下来,在遇到相同问题时拿来复用。
例如处理鸽子送信的问题,由于鸽子属于鸟类,具有鸟类相同的属性和行为,这样就节省了定义鸟和鸽子共同具有的属性和行为的时间。不过,并不是所有鸟都具有鸽子送信的能力,所以还需要再添加鸽子具有的苏特殊性和行为。
继承性主要利用特定对象之间的共有属性。
例如,矩形是四边形,矩形和四边形具有共同特性——拥有四条边,可以将矩形看作四边形的延伸。
矩形服用了四边形的属性和行为,同时添加了矩形的都有属性和行为。
将父类对象应用于子类的特征就是多态。
如下图:
长螺丝类和短螺丝类都继承了螺丝类的属性(长螺丝和短螺丝都是螺丝)。那么他们就具有相同的特性:粗细、螺纹的密度……也有不同的属性:一长一短。
一个父类衍生出了不同的子类,子类继承了父类的一些特性,同时也有自己的特性,此即多态化的结构。
对象的属性也称为成员变量。
如上面鸟类的例子:
public class Bird {
String Wings; //翅膀
String Claw; //爪子
Stirng beak; //喙
String feather; //羽毛
}
Bird
就是类,其中定义的就是成员变量。
成员方法对应于类的行为。
定义成员方法的格式:
权限修饰符 返回值类型 方法名(参数类型 参数名){
…… //方法体
return 返回值;
}
一个成员方法可以有参数,这个参数可以是对象,也可以是基本数据类型的变量,成员方法有返回值和不返回任何值的选择。
同样是上面鸟类的例子:
public class Bird {
public void Eat(String Meat){
}
public void Fly(){
}
public void Jump(){
}
}
Eat
Fly
Jump
是方法
在成员方法中定义的变量。
public String getName(){
int id = 0;
return id + this.name;
}
id
就是局部变量。
局部变量的寿命从在方法中被创建时开始****,在方法执行结束时结束。所以在两个互补嵌套的作用域中可以定义两个名称和类型完全相同的局部变量,两变量互相独立、互不干扰。
局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译错误。
成员变量不需要初始化。
像下面的程序
public class HelloJava {
String name;
public void getName(){
int id = 0;
System.out.println(id+name);
}
public static void main(String[] args) {
HelloJava test = new HelloJava();
test.getName();
}
}
定义了一个成员变量name
,一个局部变量id
,将他们输出:
0null
以上几个概念的关系:
当成员变量与局部变量重名时,可以利用this关键字来访问成员变量。
如下程序:
public class Book {
String name = "abc";
public void showName(String name){
System.out.println(name);
}
public static void main(String[] args) {
Book book = new Book();
book.showName("123");
}
}
定义了一个成员变量name
,一个局部变量name
输出结果为:
123
说明此时的name
是成员方法中的局部变量name
,而不是类中定义的成员变量。
此时如果想要调用成员变量name
,需要使用this关键字。
public class Book {
String name = "abc";
public void showName(String name){
System.out.println(this.name);
}
public static void main(String[] args) {
Book book = new Book();
book.showName("123");
}
}
输出结果:
abc
权限修饰符包括private、public和protected。
如下表:
访问包位置 | private | protected | public |
---|---|---|---|
本类 | 可见 | 可见 | 可见 |
同包的其他类或子类 | 不可见 | 可见 | 可见 |
其他包的类或子类 | 不可见 | 不可见 | 可见 |
在包Name
下新建类 Name
和Test
:
Name
中的内容:
package Name;
public class Name {
String name = "abc";
public void showName(String name){
System.out.println(this.name);
}
}
Test
中的内容:
package Name;
public class Test {
public static void main(String[] args) {
Name book = new Name();
book.showName("123");
}
}
此时,运行Test
输出正常为abc
当将Name
中的public void showName
改为private void showName
时,报错:
在src下新建包Name2
,包下新建类Test2
Test2
中内容:
package Name2;
import Name.Name;
public class Test2 {
public static void main(String[] args) {
Name book = new Name();
book.showName("123");
}
}
运行结果abc
当将Name
中的public void showName
改为private void showName
时,报错,与上图相同。
若改为protected void showName
时,Test
运行结果abc
,Test2
仍然报错。
在Java中,任何变量在被使用前都必须先设置初值,如无显式赋值,则编译器会为其进行隐性赋值。Java提供了为类的成员变量赋初值的专门方法,也就是构造方法。
构造方法是一个与类同名的方法,对象的创建就是通过构造方法来完成的。每当类实例化一个对象时,类都会自动调用构造方法。
public class Name {
public Name(){}
}
构造方法,就是创建类的对象过程中运行的方法,也就是对象的初始化方法。
构造方法没有返回值,构造方法不需要void关键字进行修饰。
1.构造方法作用:
(1)构造出来一个类的实例
(2)对构造出来个一个类的实例(对象)初始化。
2.构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void也没有。
3.主要完成对象的初始化工作,构造方法的调用是在创建一个对象时使用new操作进行的。
4.类中必定有构造方法,若不写,系统自动添加无参构造方法。
5.不能被static、final、synchronized、abstract和native修饰。
6.构造方法在初始化对象时自动执行,一般不能显式地直接调用。当同一个类存在多个构造方法时,java编译系统会自动按照初始化时最后面括号的参数个数以及参数类型来自动一一对应。
定义一个构造方法并且创建一个类的对象:
public class ClassTest {
public ClassTest(){
}
public static void main(String[] args) {
//创建这个类的对象
ClassTest test = new ClassTest();
}
}
将public ClassTest(){}
删除后:
public class ClassTest {
public static void main(String[] args) {
//创建这个类的对象
ClassTest test = new ClassTest();
}
}
并没有报错。
说明编译器自动会生成一个无参数的构造方法。
如果在类中定义的构造方法都不是无参的构造方法,则编译器不会为类设置一个默认的无参构造方法。这时试图调用无参构造方法实例化一个对象时,编译器会报错。
只有在类中没有定义任何构造方法时,编译器才会在该类中自动创建一个不带参数的构造方法
this
还可以调用类中的构造方法。
public class ClassTest {
int i;
public ClassTest(){
this(1);
}
public ClassTest(int i){
this.i=i;
}
}
上述代码中:
第一个this
调用类中的构造方法,输入了参数,所以自动识别到第二个有参数的构造方法。
第二个this
调用成员变量i
。
所以程序的运行过程为将1赋给第二个构造方法中的局部变量i
,然后将局部变量i
的值赋给成员变量i
。
public class ClassTest {
int i;
public ClassTest(){
this(1);
System.out.println(i);
}
public ClassTest(int i){
this.i=i;
System.out.println(i);
}
public static void main(String[] args) {
ClassTest test = new ClassTest(0);
ClassTest TEST2 = new ClassTest();
}
}
运行结果:
0
1
1
主方法是类的入口点,它定义了程序从何处开始。
主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须也是静态的。
主方法没有返回值。