JAVA笔记---面向过程与面向对象;类,对象;实例变量,引用;构造方法;
Posted 猿头猿脑的王狗蛋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA笔记---面向过程与面向对象;类,对象;实例变量,引用;构造方法;相关的知识,希望对你有一定的参考价值。
面向过程与面向对象:
1.面向过程思想的典型栗子是C语言,C语言实现一个程序的流程是:在主函数中一步一步地罗列代码(定义子函数来罗列也是一样的道理),以此来实现我们想要的效果;
2.面向对象思想的典型栗子是Java语言,Java是一种完全面向对象的语言,它实现一个程序的流程是:事先从我们创建的对象中挑选需要的对象,让他们做出各自的行为,以此来实现我们想要的效果;
3.两者的区别:面向过程思想的耦合性强,扩展性差,这样会导致用面向过程写出来的程序相对于面向对象写出来的程序适用范围小很多;但是对于小型项目来说,面向过程的效率可能会更高一些,因为它不需要像面向对象那样,先进行对象的提取,然后再开始编程,面向过程上来就是干,就是整;
类:
1.模板:
class 类名 { 变量;方法;}
2.概念:
类是我们程序员虚构出来的东西,比如说我们要创建车类,我们会将它的属性和行为以代码的方式提炼出来,属性就相当于变量,行为就相当于方法,把两者写到类体里,一个 class 车(车类)就创建好了;
3.使用:
一般我们通过在主方法将类实例化为对象进行使用;
对象:
1.对象创建:
对象是new出来的,eg:Student xiaoMing = new Student( ) ; // 等价于: 引用数据类型 变量名 = new 构造方法( ) ; // ” new Student ( ) “是用学生类创建出来的学生对象 小明;
new 是一个运算符,如上述栗子中 new作用就是:在堆内存中为Student( )构造方法中的每个实例变量分配空间,这些所有的实例变量都可以用一个地址来找到,这个地址就被存到了 s1 中,s1 属于引用数据类型的变量,他的引用数据类型就是Student;
2.类与对象的关系:
类( 实例化 )=对象,对象( 抽象化 )=类 ; 所以说对象其实就是一种特殊的类,它的模板就是类,只不过对象属于现实生活中实际存在的事物,而类是我们虚构的;
实例变量与引用:
1.实例变量其实就是我们在定义类时,对于现实事物进行属性提取,将其表达为变量的形式,这种变量就是实例变量;
2.实例变量格式: 在数据类型前没有 “ static ”修饰的变量都是实例变量;
3.引用好比做 C语言 中的指针变量,它储存了对象内存地址的变量;
如下图:
a 就是 Address(引用数据)类型的变量,其中储存了堆内存中的那个 Address 类型对象的地址;Address 是一个我们定义好的 Address 类的类名,它的类体中定义了三个 String 类型的变量,此时它被实例化为一个对象;所以此时就可以通过“ a . 属性( city/steet/zipcode) ”的方式来访问这三个实例变量中的数据( 北京/ 大兴区/ 121221)了;对于图中的 User(引用数据)类型的变量 u 也是同理,它指向了堆内存中的那个 User 对象;
注意:所有实例变量的访问必须通过” 引用 . “的方式访问;静态变量用” 类名 . “的方式访问,其实也可以用” 引用 . “的方式来访问,但是其实在运行阶段,它还是会被当作” 类名 . “来进行访问,所以没必要用” 引用 . ”的方式来访问静态变量( 程序员的一个好习惯 );
构造方法:
1.构造方法也属于方法的一种,方法分为普通方法与构造方法,每个类体中都必须至少有一个构造方法,如果没有的话,系统会自动提供一个无参的构造方法(缺省构造器)(为所有类体中的实例变量赋默认值);
2.构造方法的作用是为类体中的实例变量赋值,方法体中为空也可以,因为系统会在方法体中自动给实例变量赋默认值(在对象创建时),比如 int 类型的实例变量初始默认值就是0,boolean 类型的初始默认值是 false 等等,这也是为什么“实例变量不进行初始化也不会报错”的原因,因为在调用相应的构造方法时,如果实例变量咱们没有在此构造方法中手动赋值,系统就会赋默认值;
3.格式: public 方法名(有参/无参) { 方法体 }
注意: 访问权限修饰符必须用 public ;不要用 static 修饰方法 ;返回值类型不要写 ;
辅助理解代码:
public class A {
//源文件类名
int a;
String b;
public A() {
//a = 0;
//b = null;
// 方法体为空,系统为所有未赋值的实例变量赋默认值
}
public A(int a,String b){
this.a=a;
this.b=b;
//当然书写一个有参方法,一股脑儿的将所有实例变量赋值也不是必要的,根据程序员自己的需求,利用方法重载来书写多个构造方法,到时候用哪个调用哪个就行,如下代码:
}
public A(int a){
this.a=a;
//b 被系统赋默认值 null
}
public A(String b){
this.b=b;
//a 被系统赋默认值 0
}
}
上方代码还涉及到一个新的知识: “ this ” :
1.“ this ”等价于当前对象,比如说在 A 类中,“ this . ”就等价于“ A . ”;
2.在我看来 this 就一个用途:在类中,书写一个有参构造方法时,我们需要在方法名()的()中书写形参的数据类型以及变量名,而取名当然“ 见名知意 ”最好,所以干脆就为 形参 取 与之对应的实例变量的变量名,那么方法体中又怎样区分名字相同的 实例变量 和 形参 呢?如上方代码 :this . a = 实例变量 a ; a = 形参 a(遵循就近原则)
随笔:
1.引用数据类型:
1).概念:引用数据类型包括 String 类型 和 我们自己手动创建的引用数据类型;Java中所有的 “ 类 “ 都属于引用数据类型;
2).引用数据类型的变量中装的是地址,地址指向堆内存中的对象
2.OOA---面向对象分析;OOD---面向对象设计;OOP面向对象编程;
实现一个软件的过程:分析---设计---编程;
3.静态变量的赋值在类加载时完成,而实例变量在用构建方法创建对象时完成赋值;
由于博主目前还没有将 Java-SE 的知识都学完,所以有些地方可能说的有些片面,若前辈们能够指点一二就更好了 (~ ̄(OO) ̄)ブ
JAVA学习笔记面向对象
- 编程语言的发展
- 面向过程的设计思想
- 面向对象的设计思想
- 对象和类的概念
- 类之间的关系
- 对象和引用
- Java类的定义
- 构造函数
- 对象的创建和使用
- this关键字
- static关键字
- package和import语句
- 访问控制
- 类的继承
- 方法的重写
- final关键字
- object类
- 对象转型
- 多态
- 抽象类
- 接口
编程语言的发展
- 机器语言
- 汇编语言
- 高级语言–面向过程的语言
- 面向对象的语言
面向过程的思想和面向对象的设计思想
面向对象思维:
- 合适的方法出现在合适类中
在问题域中,不再考虑一步一步的过程,而是将问题域中的对象抽象出来,弄清楚对象和对象之间的关系。
重点:面向对象实现的三个步骤:
- 问题中有哪些类哪些对象。
- 这些类这些对象有哪些属性和方法。
- 类和类之间具备哪些关系:关联(弱),继承(强),聚合(强),实现(父类和子类之间),多态。
对象和类的概念
- 类:一类事物的一个抽象,包括静态属性(成员变量)和动态属性(方法)。“瓶子”
对象:一类事务的具体的实例。“某个瓶子”
类(对象)之间的关系 之
关联关系
关联关系:某个类的方法关联到某个类的对象。
继承关系(一般和特殊)
容易形成继承树
XX是一种XX:球类运动员是一种运动员。
一类可以从不同的多个类继承。【多重继承:C++】
聚合关系(整体和部分)
聚集:松耦合
组合:必不可少
实现关系
父类的方法,子类来实现。
多态
练习:
类:旅行社,旅客,机票,账目
机票
属性:班次
方法:送票,作废,显示航班时间
Java与面向对象
必须先定义类才能有对象
- 对象是Java程序的核心,在Java程序中“万事万物皆对象”。
- 对象可以看成是静态属性(成员变量)和动态属性(方法)的封装体。
- 类是用来创建同一类对象的“模板”,在一类中定义了该类对象所应具有的成员变量及方法。
- J2SDK本身提供了很多类供编程人员使用,编程人员也可定义自己的类。
为什么用对象?
Java类的定义
约定俗成的命名规则:
- 类名的首字母大写
- 变量名和方法名的首字母小写
- 运用驼峰标识
//用class关键字定义一个类,例如:
class Person{
//成员变量定义
private int id;
private int age = 20;
//方法定义
public int getAge(){
return age;
}
public void setAge(int i){
age = i;
}
public int getId(){
return id;
}
}
成员变量
成员变量可以使Java语言中任何一种数据类型(包括基本类型和引用类型)。
在定义成员变量时,可以对它初始化,也可以不对它初始化,不初始化时,Java会给出默认初始化值。
成员变量的作用范围为整个类体。
引用
Java中除了基本类型之外的变量类型都称为引用类型。
Java中的对象是通过引用对其操作。
- 基本类型:占一块内存。
- 引用类型:占两块内存(一小块内存指向一大块内存)。(引用(栈) + 真正的对象(存放在堆内存中))
类和对象的关系
构造方法(构造函数)
- 使用new+构造方法 创建一个新对象。
- 构造函数是定义在Java类中的一个用来初始化对象的函数。
构造函数与类同名且没有返回值。
public class Person{ int id; int age; Person(int n,int i){ id = n; age = i; } }
创建对象时,使用构造函数初始化对象的成员变量。
public class Test{ public static void main(String args[]){ Person tom = new Person(1,25); Person john = new Person(2,27); } }
当没有指定构造函数时,编译器为类自动添加形如:类名( ){ } 的构造函数。
class Point{ public int x; public int y; } ... Point p = new Point();
方法重载
方法的重载是指一个类中可以定义有相同的名字,但参数不同的多个方法。调用时,会根据不同参数表选择对应的方法。
void info() { System.out.println("my id is :" + id); } void info(String t) { System.out.println(t + " my id is" + id); }
构造方法也可以重载。
Person() { id = 100; age = 20; } Person(int _id) { id = _id; age = 30; } Person(int _id, int _age) { id = _id; age = _age; }
对象创建与使用
- 必须使用 new 关键字创建对象
- 使用对象【引用.成员变量】来引用对象的成员变量
- 使用对象【引用.方法(参数列表)】来调用对象的方法
- 同一类的每一对象有不同的成员变量存储空间
- 同一类的每个对象共享该类的方法
- 非静态方法是针对每个对象进行调用
this 关键字
- 在类的方法定义中使用的this关键字代表使用该方法的对象的应用
- 在必须指出当前使用方法的对象是谁时要使用this
- 有时使用this可以处理方法中成员变量和参数重名的情况
this可以看作是一个变量,它的值时当前对象的引用
public class Leaf{ int i = 0; Leaf(int i ){ this i = i; } Leaf increament() { i++; return this; } void print(){ System.out.println("i = "+i); } public static void main(String[] args){ Leaf leaf = new Leaf(100); leaf.increament().increament().print(); } }
static 关键字
- 在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。
- 用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。
- 静态方法不再是针对某个对象调用,所以不能访问非静态成员。
- 可以通过对象引用或类名(不需要实例化)访问静态成员。
package 和 import 语句
为了便于管理大型软件系统中数目众多的类,解决类的命名冲突问题,Java引入包(package)机制,提供类的多重类命名空间。
- 如果想把一个类放入包中,在这个类源文件第一句话写package
- 必须保证该类的class文件位于正确目录下
- 该类的源码可能会产生影响
- 删除或转移到另外的目录
- 另外的类想访问的话
- 写全名
- 引入
- *
- 具体类名
- 访问位于同一个包中的类不需要引入
- 必须class文件的最上层包的父目录位于classpath下
- 执行一个类需要写全包名
J2SDK 中主要的包介绍
- java.lang 包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
- java.awt 包含了构成抽象窗口工具类(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
- java.applet 包含applet运用所需的一些类。
- java.net 包含执行与网络相关的操作的类。
- java.io 包含能够提供多种输入/输出功能的类。
- java.util 包含一些实用工具类,如定义系统特性、实用与日期日历相关的函数。
- java.lang包中的类,不需要引入,可以直接使用。
- 把自己的类打成jar包:jar -cvf xxx.jar * . *
类的继承
Java中使用extends关键字实现类的继承机制,其语法规则为:
<modifier> class <name> [extends <superclass>] { ... ... }
通过继承,子类自动拥有了基类(superclass)的所有成员(成员变量和方法)。
Java只支持单继承,不允许多继承:
- 一个子类只能有一个基类,一个基类可以派生出多个子类
//继承中的权限控制 class Parent{ private int n_private = 1; int n_friendly = 2; // 包权限:同一个包内可以访问 protected int n_protected = 3; public int n_public = 4; } class Child extends Parent { public void f () { // n_private = 10; 错误,继承中私有变量不能访问 n_friently = 20; n_protected = 30; n_public = 40; } }
访问控制
Java权限修饰符public protected private 置于类的成员定义前,用来限定其他对象对该类对象成员的访问权限。
对于class的权限修饰只可以用 public 和 default
- public 类可以在任意地方被访问
- default 类只可以被同一个包内部的类访问
方法重写
在子类中可以根据需要对从基类中继承来的方法进行重写
重写方法必须和被重写方法具有相同方法名称,参数列表和返回类型
重写方法不能使用比被重写方法更严格地访问权限
super 关键字
在Java类中使用 super 来引用基类的成分,例如:
class FatherClass { public int value; public void f () { value = 100; System.out.println("FatherClass.value = "+value); } } class ChildClass extends FatherClass { public int value; public void f () { super.f(); //super指向当前对象的父对象 value = 200; System.out.println("ChildClass.value ="+value); System.out.println(value); System.out.println(super.value); } }
继承中的构造方法
- 子类的构造的过程中必须调用其基类的构造方法。
- 子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法。
- 使用this(argument_list)调用本类的另外的构造方法
- 如果调用super,必须写在子类构造方法的第一行
- 如果子类的构造方法中没有显示地调用基类构造方法,则系统默认调用基类无参数的构造方法
- 如果子类构造方法中既没显示调用基类构造方法,而基类中又没有无参的构造方法,则编译出错。
参数拷贝来拷贝去,最终剩下堆里的对象和栈里的引用以及数据区的静态变量。
Object类
- Object 类是所有Java类的根基类
如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类
public class Person { ... ... }
等价于:
public class Person extends Object{ ... ... }
toString 方法
- Object 类中定义有public String toString() 方法,其返回值是String类型,描述当前对象的有关信息
- 在进行String与其它类型数据的连接操作时(如:System.out.println(“info”+person)),将自动调用该对象类的toString() 方法
- 可以根据需要在用户自定义类型中重写toString()方法
hashcode 解释
每一个对象都有一个独一无二的哈希编码,可以通过这个哈希编码在内存中找到这个对象并确定这个对象的位置。
equals 方法
- public boolean equals(Object obj)方法
- 定义对象是否“相等”的逻辑
- Object 的 equals方法定义为:x.equals(y)当x和y是同一个对象的引用时,返回true否则返回false
- J2SDK提供的一些类,如String,Date等,重写了Object的equals方法,调用这些类的equals方法,x.equals(y),当x和y所引用的对象是同一类对象且属性内容相等时(并不一定是相同对象),返回true否则返回false
可以根据需要在用户自定义类型中重写equals方法
public class TestEquals { public static void main(String[] args) { Cat c1 = new Cat(1,2,3); Cat c2 = new Cat(1,2,3); //类Cat重写从Object类默认集成的方法equals() System.out.println(c1 == c2); //false System.out.println(c1.equals(c2)); //true //String类已经中重写了方法equals() String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); //false System.out.println(s1.equals(s2)); //true } } class Cat { int color; int height, weight; public Cat(int color, int height, int weight) { this.color = color; this.height = height; this.weight = weight; } public boolean equals(Object obj) { if(obj == null) return false; else { if(obj instanceof Cat) { Cat c = (Cat)obj; if(this.color == c.color && this.height == c.height && this.weight == c.weight) { return true; } } } return false; } }
对象转型(casting)
- 一个基类的引用类型变量可以“指向”其子类的对象
- 一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)
- 可以使用引用变量 instanceof 类名来判断该引用型变量所“指向”的对象是否属于该类或该类的子类。
子类的对象可以当做基类的对象来使用称为向上转型(upcasting),反之称为向下转型(downcasting)。
class Animal { public String name; Animal (String name) { this.name = name; } } class Cat extends Animal { public String eyesColor; Cat (String n, String c) { super(n); eyesColor = c; } } class Dog extends Animal { public String furColor; Dog (String n, String c) { super(n); furColor = c; } }
public class Test { public static void main(String args[]) { Animal a = new Animal("name"); Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname","black"); System.out.println(a instanceof Animal); //true System.out.println(c instanceof Animal); //true System.out.println(d instanceof Animal); //true System.out.println(a instanceof Cat); //false a = new Dog("bigyellow","yellow"); System.out.println(a.name); //bigyellow //System.out.println(a.furname); //!error System.out.println(a instanceof Animal); //true System.out.println(a instanceof Dog); //true Dog d1 = (Dog)a; //要加强制转换符 System.out.println(d1.furColor); //yellow } }
public class Test { public static void main(String args[]) { Test test = new Test(); Animal a = new Animal("name"); Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname", "black"); test.f(a); test.f(c); test.f(d); } public void f(Animal a) { System.out.println("name: "+a.name); if(a instanceof Cat) { Cat cat = (Cat)a; System.out.println(" "+cat.eyesColor+" eyes"); } if(a instanceof Dog) { Dog dog = (Dog)a; System.out.println(" "+dog.furcolor+ "fur"); } } }
动态绑定和多态
- 动态绑定:是指在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法
下面的例子中,根据Lady对象的成员变量pet所引用的不同的实际类型而调用相应的enjoy方法
class Animal { private String name; Animal (String name) { this.name = name;} private void enjoy() { System.out.println("叫声。。。。。"); } } class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c;} public void enjoy() { System.out.println("猫叫声。。。。。"); } } class Dog extends Animal { private String furColor; Cat(String n, String c) { super(n); furColor = c;} public void enjoy() { System.out.println("狗叫声。。。。。"); } } class Lady { private String name; private Animal pet; Lady(String name, Animal pet) { this.name = name; this.pet = pet; } public void myPetEnjoy() { pet.enjoy(); } } public class Test { public static void main(String args[]) { Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname","black"); Lady l1 = new Lady("l1",c); Lady l2 = new Lady("l2",d); l1.myPetEnjoy(); l2.myPetEnjoy(); } }
- 多态的存在有三个必要条件:
- 要有继承;
- 要用重写;
- 父类引用指向子类对象;
抽象类
- 用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。
- 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
- 抽象类不能被实例化。
抽象方法只需声明,而不需实现。
abstract class Animal { private String name; Animal (String name) { this.name = name; } public abstract void enjoy(); } class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c; } public void enjoy() { System.out.println("猫叫声。。。。"); } }
Final关键字
- final 的变量的值不能够被改变
- final 的成员变量
- final 的局部变量(形参)
- final 的方法不能够被重写
final 的类不能被继承
接口
- 接口(interface)是抽象方法和常量值的定义的集合。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
//接口中没有abstract,但是所有的都是abstract public interface Runner { //public static final int id = 1; int id = 1; //默认是public static final 关键字写不写都行 public void start(); public void run(); public void stop(); }
接口特性
- 接口可以多重实现 (意思:可以实现多继承)
- 接口中声明的属性默认为 public static final 的,也只能是public static final
- 接口中只能定义抽象方法,而且这些方法默认为pubic的,也只能是public的
- 接口可以继承其他的接口,并添加新的属性和抽象类
- 多个无关的类可以实现同一个接口
- 一个类可以实现多个无关的接口
- 与继承关系类似,接口与实现类之间存在多态性
定义Java类的语法格式:
<modifier> class <name> [extends <superclass>] [implements <interface> [, <interface>]* ] { <declarations>*}
interface Singer { public void sing(); public void sleep(); } class Student implement Singer { private String name; Student(String name) { this.name = name; } public void study() { System.out.println("studying"); } public String getName() { return name; } public void sing() { System.println("Student is singing"); } public void sleep() { System.out.println("Student is sleeping"); } }
interface Singer { public void sing(); public void sleep(); } interface Painter { public void paint(); public void eat(); } class Student implement Singer { private String name; Student(String name) { this.name = name; } public void study() { System.out.println("studying"); } public String getName() { return name; } public void sing() { System.println("Student is singing"); } public void sleep() { System.out.println("Student is sleeping"); } } class Teacher implements Singer,Painter { private String name; public String getString() { return name; } Teacher(String name) { this.name = name; } pulic void teach() { System.out.println("teaching"); } pulic void sing() { System.out.println("teaching is singing"); } pulic void sleep() { System.out.println("teaching is sleeping"); } pulic void paint() { System.out.println("teaching is painting"); } pulic void eat() { System.out.println("teaching is eating"); } } public class TestImplement { public static void main (String[] args) { Singer s1 = new Student("le"); s1.sing(); s1.sleep(); Singer s2 = new Teacher("steven"); s2.sing(); s2.sleep(); Painter p1 = (Painter)s2; p1.paint(); p1.eat(); } }
总结
- 对象和类的概念
- 类(对象)之间的关系
- 面向对象思想
- class
- new
- 引用的概念
- 构造方法的概念
- 方法重载
- 构造方法重载
- this
- static
- package & import
- private default protected public
- extends
- overwrite
- final
- Object
- toString
- equals
- upcasting downcasting
- polymophysm / dynamic binging / late binging
- abstract class
- interface
- implements
以上是关于JAVA笔记---面向过程与面向对象;类,对象;实例变量,引用;构造方法;的主要内容,如果未能解决你的问题,请参考以下文章
[52PJ] Java面向对象笔记(转自52 1510988116)
Java笔记(面向对象,类,this关键字,封装(private),匿名对象,成员变量和局部变量)