本章概述
“如何开车”:(由多个步骤组成),简单问题,可以使用面向过程。
“如何造车”:(成千上万个零件,细节很多),复杂问题,宏观上用面向对象把握,微观操作用面向过程(方法、函数等)
对象:
是具体的事物 xiaoming xiaohong
类:
是对对象的抽象(抽象 抽出象的部分)Person先有具体的对象,然后抽象各个对象之间象的部分,归纳出类通过类再认识其他对象。
生活案例
类是一个图纸 对象是根据该图纸制造多个实物
类是一个模具 对象是使用模具制造的多个铸件(月饼模子 )
类是上海大众汽车,对象就是大家购买的一辆辆具体上海大众汽车
分析:由多个具体的人(小红、 小张、 老李) 抽象出所有的公共特征静态特征: 姓名、 年龄、 性别动态行为: 吃饭、 休息、 自我介绍实现:创建抽象的人-----Person类创建具体的人-----对象
类: class。
对象: Object, instance(实例)
对象和类的关系
• 特殊到一般, 具体到抽象。
• 类可以看成一类对象的模板, 对象可以看成该类的一个具体实例。
• 类是用于描述同一类形的对象的一个抽象的概念, 类中定义了这一类对象所应具有的静态和动态属性。
• JDK提供了很多类供编程人员使用, 编程人员也可定义自己的类。
• 定义类(类的组成)——属性 field——方法 method——构造方法 construtor——其他: 代码块 静态代码块 内部类• 创建对象——类名 对象名 = new 类名();——Person p1=new Person();• 调用类的属性和方法——对象名.成员变量——对象名.成员方法
属性 field, 或者叫成员变量
• 属性用于定义该类或该类对象包含的数据或者说静态属性。
• 属性作用范围是整个类体
• 属性定义格式:
在定义成员变量时可以对其初始化
如果不对其初始化, Java使用默认的值对其初始化
局部变量和成员变量
• 区别
• 声明位置不同 :方法中 , 类中
• 作用范围不同: 当前方法 , 当前类的方法
不同的方法中即使有同名的局部变量, 没有关系, 互不影响,建议相同
• 内存存放的位置的: 堆内存中 栈内存中
• 成员变量有默认值; 局部变量没有默认值
引用类型
• Java 语言中除基本类型之外的变量类型都称之为引用类型
Java中的对象和数组是通过引用对其操作的.引用可以理解为一种受限的指针指针是可以进行与整数做加减运算的, 两个指针之间也可以进行大小比较运算和相减运算。 引用不行, 只能进行赋值运算。引用就是一个变量或对象的别名(引用的本质是一个对象)。指针是一个段内存空间的地址(指向存储一个变量值的空间或一个对象的空间)
内存分析
• 栈:
存放: 局部变量
先进后出, 自下而上存储
方法执行完毕, 自动释放空间
• 堆:
存放new出来的对象
需要垃圾回收器来回收
• 方法区:
存放: 类的信息(代码)、 static变量、 字符串常量等.
public class SxtStu {//属性fieldsint id;String sname;int age;Computer comp; //计算机//方法void study(){System.out.println("我在认真学习!!,使用电脑:"+comp.brand);}void play(){System.out.println("我在玩游戏!王者农药!"); }//构造方法。用于创建这个类的对象。无参的构造方法可以由系统自动创建。SxtStu(){System.out.println("调用了无参的构造方法!");}//程序执行的入口,必须要有//javac Sxtstu.java , java Sxtstupublic static void main(String[] args) {SxtStu stu = new SxtStu(); //创建一个对象stu.id=1001;stu.sname= "高淇";stu.age = 18;Computer c1 = new Computer();c1.brand = "联想";p = c1;stu.play();stu.study();}}class Computer {String brand;}
构造器
• 构造器定义: constructor 构造方法
一个在创建对象时被自动调用的特殊方法。
• 构造器作用:为对象进行初始化(成员变量) 工作。
• 构造器是一种特殊的方法:构造器的方法名必须和类名一致!
• 构造器虽然有返回值, 但是不能定义返回类型(返回值的类型肯定是本类), 不能在构造器里调用return。
• 通过new关键字调用! !
• 如果我们没有定义构造器, 则系统会自动定义一个无参的构造方法。 如果已定义则编译器不会添加无参数构造方法!
• 与普通方法一样, 构造方法也可以重载
示例
• 定义一个“点” (Point) 类用来表示二维空间中的点(有二个坐标) 。 要求如下:
可以生成具有特定坐标的点对象;提供可以设置二个坐标的方法;提供可以计算该“点” 距另外点距离的方法。
class Point {double x, y;//构造方法名称和类名必须保持一致public Point(double _x, double _y) {x = _x;y = _y; }Point(){}public double getDistance(Point p) {return Math.sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));}}public class TestConstructor {public static void main(String[] args) {Point p = new Point(3.0, 4.0);Point origin = new Point(0.0, 0.0);Point p2 = new Point();System.out.println(p.getDistance(origin));}}
方法调用
• 形参和实参
——定义方法的参数是形式参数
——调用方法的参数是实在参数
——调用方法时要求参数个数相同, 类型兼容
• 参数传递
基本数据类型的参数传递:无法通过方法调用改变变量的值
引用数据类型的参数传递:可以通过方法调用改变变量的值
this关键字
• this的作用:
——this表示的是当前对象本身,
——更准确地说, this代表当前对象的一个引用。
• 普通方法中使用this:
——区分类成员属性和方法的形参。
——调用当前对象的其他方法(可以省略)
——位置: 任意
• 构造方法中使用this:
——使用this来调用其它构造方法
——位置: 必须是第一条语句
• this不能用于static方法。 (讲完static, 大家就知道为什么了! )
this 测试代码
static 关键字
在类中, 用static声明的成员变量为静态成员变量 ,或者叫做: 类属性, 类变量.• 它为该类的公用变量, 属于类, 被该类的所有实例共享, 在类被载入时被显式初始化,
• 对于该类的所有对象来说, static成员变量只有一份。 被该类的所有对象共享! !
• 可以使用” 对象.类属性” 来调用。 不过, 一般都是用“类名.类属性”
• static变量置于方法区中!用static声明的方法为静态方法
• 不需要对象, 就可以调用(类名.方法名)
• 在调用该方法时, 不会将对象的引用传递给它, 所以在static方法中不可访问非static的成员。
• 静态方法不能以任何方式引用this和super关键字
Static示例代码
静态初始化块
• 如果希望加载后, 对整个类进行某些初始化操作, 可以使用static初始化块。
• 类第一次被载入时先执行static代码块; 类多次载入时, static代码块只执行一次; Static经常用来进行static变量的初始化。
• 是在类初始化时执行, 不是在创建对象时执行。
• 静态初始化块中不能访问非static成员。
pakage
为什么需要package?• 为了解决类之间的重名问题。
• 为了便于管理类: 合适的类位于合适的包!package怎么用?
• 通常是类的第一句非注释性语句。
• 包名: 域名倒着写即可, 再加上模块名, 并与内部管理类。注意事项:
• 写项目时都要加包, 不要使用默认包。
• com.gao和com.gao.car, 这两个包没有包含关系, 是两个完全独立的包。 只是逻辑上看起来后者是前者的一部分。
JDK中的主要包
java.lang• 包含一些Java语言的核心类, 如String、 Math、 Integer、 System 和Thread, 提供常用功能。java.awt
• 包含了构成抽象窗口工具集(abstract window toolkits) 的多个类, 这些类被用来构建和管理应用程序的图形用户界面(GUI)。
• 包含执行与网络相关的操作的类。java.io
• 包含能提供多种输入/输出功能的类。java.util
• 包含一些实用工具类, 如定义系统特性、 使用与日期日历相关的函数。
Import
为什么需要import?• 如果不适用import, 我们如果用到其他包的类时, 只能这么写: java.util.Date, 代码量太大, 不利于编写和维护。 通过import可以导入其他包下面的类, 从而可以在本类中直接通过类名来调用。import怎么使用?
• import java.util.Date;
• import java.util.*; //导入该包下所有的类。 会降低编译速度, 但不会降低运行速度。注意要点:
• java会默认导入java.lang包下所有的类, 因此这些类我们可以直接使用。
• 如果导入两个同名的类, 只能用包名+类名来显示调用相关类:
• java.util.Date date = new java.util.Date();
import static
静态导入的作用: 用于导入指定类的静态属性• JDK5.0后增加!如何使用:
• import static java.lang.Math.*;//导入Math类的所有静态属性
• import static java.lang.Math.PI;//导入Math类的PI属性
• 然后, 我们可以在程序中直接使用: System.out.println(PI);
总结代码
/*** 测试参数传值机制**/public class User4 {int id; //idString name; //账户名String pwd; //密码public User4(int id, String name) {this.id = id;this.name = name;}public void testParameterTransfer01(User4 u){u.name="高大";}public void testParameterTransfer02(User4 u){u = new User4(200,"高三");}public static void main(String[] args) {User4 u1 = new User4(100, "高小");u1.testParameterTransfer01(u1); System.out.println(u1.name); //高大u1.testParameterTransfer02(u1);System.out.println(u1.name); //高大}
/*** 测试静态初始化块的使用**/public class User3 {int id; //idString name; //账户名String pwd; //密码static String company; //公司名称static {System.out.println("执行类的初始化工作");company = "北京000";printCompany();} public static void printCompany(){System.out.println(company);} public static void main(String[] args) {User3 u3 = null;}}
/*** 测试static关键字的用法**/public class User2 {int id; // idString name; // 账户名String pwd; // 密码static String company = "北堂"; // 公司名称public User2(int id, String name) {this.id = id;this.name = name;}public void login() {printCompany();//非静态方法可以调用静态方法System.out.println(company); //非静态方法可以调用静态变量System.out.println("登录:" + name);}public static void printCompany() {// login();//静态方法调用非静态成员,编译就会报错System.out.println(company);}public static void main(String[] args) {User2 u = new User2(101, "高小");User2.printCompany();//静态方法可以调用静态方法pany = "北里爷";User2.printCompany();}}