目录
本周开始学习面向对象。
一、 面向对象学习
1、快速熟悉面向对象
1.1表格结构和类结构
实际上,"表格思维"是一种典型的面向对象思维。互联网上所有的数据本质上都是"表格",我们通过表格引入类和对象,原来,"表格就是对象"。
以表格为例,第一行的表格的结构field即为类,下面几行每一行对应一个对象。
不难看出,类比表格只是增加了数据类型而已。
1.2表格的动作和类的方法
在类中定义了一个方法来表示表格中动作的说明。
2、面向过程和面向对象思想
2.1面向过程和面向对象的区别
面向过程适合简单、不需要协作的事务,重点关注如何执行。面向过程是执行者思维。
面向对象思考的是怎么设计这个事物,而不是按什么步骤去执行。面向对象是设计者思维。
比如设计车的时候:先思考车的对象组成, 但制造车的每一个对象时需要执行者(面向过程思维)。
3、对象和类的详解
3.1类和对象的概念
类:我们叫做class
对象:我们叫做Object,instance(实例)。
study a=new study();//这里的a就是study类的一个对象
类是对象的一个模板。
3.2类的定义
//每一个源文件必须有且只有一个public class,并且类名和文件名保持一致!
public class Car{
}
class Type{
}
class Seat{//一个java文件可以同时定义多个class
}
以上的定义都是空类,没有任何意义,因此要定义类的具体信息。对于一个类来说,一般有三种常见的成员:属性field、方法method、构造器constructor。这三种成员都可以定义零个或多个。
public class SxtSut{
//属性(成员变量)
int id;
String sname;
int age;
//方法
void study(){
System.out.println("我在学习java!");
}
//构造方法(与类名保持一致)
SxtStu(){
}
}
3.3属性(field 成员变量)和方法
属性:属性用于定义该类或该类对象包含的数据或者说静态特征,属性的作用范围是整个类体,在定义成员变量时可以对其初始化,如果不初始化,java使用默认的值对其初始化。整型0,浮点型0.0,字符型"\u0000",布尔类型false,所有引用类型null。
方法:方法用于定于该类或该类实例的行为特征或者功能实现。方法是类和对象行为特征的抽象。与之前所讲到的方法一致。
public class study3{
//属性(成员变量)
int id;
String sname;
int age;
//方法
void study(){
System.out.println("我在学习java!");
}
//构造方法(与类名保持一致)
study3(){//如果没有这个定义,编译器会自动默认带上这个无参构造
}
public static void main(String[] args){//java中所有方法都要在class里面,因此main也要,但其实main只是形式上存在于class内部。
study3 s1=new study3();
System.out.println(s1.id);//0
System.out.println(s1.sname);//null
s1.id=1001;
s1.sname="ss";
System.out.println(s1.id);
System.out.println(s1.sname);
}
}
4、构造方法和构造器
4.1构造方法基础用法(难点)
我觉得此处比较难理解,因此举例较多。
构造器也叫构造方法(constructor),用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。构造器的名称应该和类的名称一致。Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。
构造器的4个要点:
1、构造器一定要通过new关键字调用
2、构造器虽然有返回值,但是不能定义返回值(返回值的类型肯定是本类),不能使用return
3、如果没有定义构造器,编译器会自动定义一个无参的构造函数,如果已经定义了就不会
4、构造器方法一定要与类名一致
析构方法:构造方法其实也是一种方法,只是比较特殊,程序在调用对象的时候会自动调用构造,无需手动调用,而且只会调用一次。
对比下面的图可以看出,c++和java的析构方法是一致的,都是会在调用对象的时候自动调用构造。
下面是求两点距离的两种解决方案:不难看出,因为析构方法在调用对象时会自动调用,不需要像图1一样再写一个成员方法去赋值,所以析构方法主要是进行为对象成员赋初始值(如图2),即在构造方法里就实现赋值,非常方便。
//通过成员方法实现
package studyday1;
public class study4{
double x;
double y;
void point(double _x, double _y) {
x = _x;
y = _y;
}
double set(study4 a){
return ((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
}
study4() {}
public static void main(String[] args) {
study4 a=new study4();//一定要有这么一行,不然没法对成员变量进行赋值
study4 b=new study4();
a.point(3.0,4.0);
b.point(0.0,0.0);
System.out.println(a.set(b));
}
}
package studyday1;
public class study4{
double x,y;
study4(double _x,double _y) {//构造方法
x = _x;//在构造方法里直接实现初始化赋值。
y = _y;
}
double set(study4 a){//参数是main中传进来的另一个类
return ((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
}
public static void main(String[] args){
study4 a=new study4(3.0,4.0);//因为使用了含参的成员变量,因此在new的时候也要带上参数。
study4 b=new study4(0.0,0.0);
//可以发现在main方法里面就没有再次调用其他方法进行成员的初始化了,直接在调用方法的时候就已经使用了构造函数
System.out.println(a.set(b));//调用a这个类中的set成员方法,参数使用的是b这个类。
}
}
4.2构造器的重载
与方法的重载一致,这里使用了this,要记住。
package studyday1;
public class study4 {
int id;
String name;
study4(int id){
this.id=id;
}
study4(int id,String name){
this.id=id;//this指向的是被调用的成员所属的对象。是成员里的id。
this.name=name;
}
public static void main(String[] args){
study4 a=new study4(5);
study4 b=new study4(4,"张三");
}
}
5、面向对象的内存分析
5.1java虚拟机内存模型概念
作为了解学习此部分,具体内容可以上网搜索了解。
5.2垃圾回收原理的算法
使用new操作符在堆中开辟数据,在c++中由程序员自己释放内存,在java中系统会自动释放内存。该部分内容也仅作为了解。
6、java关键字
6.1this关键字
在调用的时候,会默认传入this指向创建好的对象的地址。
this关键字调用重载:
package studyday1;
public class study4 {
int id;
String name;
String pwd;
public study4(int id,String name){
this.id=id;
this.name=name;
}
public study4(int id,String name,String pud){
this(id,name);//this()可以用于调用其他构造器,且必须位于第一行
//不能这么使用study4(id,name);
this.pwd=pwd;
}
public static void main(String[] args){
}
}
6.2static关键字
1、static定义的都属于类里面,而不从属于对象。
2、非静态方法不能通过类名调用,而静态方法可以。
3、非静态方法可以访问静态成员和非静态成员。
package studyday1;
public class study5 {
int id;
String name;
String pwd;
static String company="公司";
public study5(int id,String name){
this.id=id;
this.name=name;
}
public void login(){
ss();//静态成员变量属于类,因此在这里可以调用,编译不会报错。
System.out.println("名字"+name);
}
public static void ss(){
//login();//调用非静态成员,编译就会报错。因为这里还没有建立对象,所以对非静态成员变量无法调用,比如id和name以及login都不行
System.out.println("我的公司");
}
public static void main(String[] args){
study5 a=new study5(100,"张三");
study5.ss();
study5.company="我的公司2";
System.out.println(study5.company);
}
}
类被加载不一定有对象,因此非静态变量并不一定存在,因此在静态成员变量里面是不能够调用的。而如果对象存在,类一定已经被加载,而类被加载静态成员变量一定已经存在,因此可以在对象里面调用静态成员变量。
6.3package包机制
包机制是java中管理类的重要手段,开发中我们会遇到大量同名的类,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理。包对于类,相当于文件夹对于文件的作用。
package:我们通过package实现对类的管理,package使用的两个要点:
1、通常是类的第一句非注释性语句
2、包名:域名倒着写即可,再加上模块名,便于内管理类。
package命名演示
com.sum.text;//com和sum换了位置
com.oracle.text;
cn.sxt.ji.text;
cn.sxt.ji.vied;
注意事项:
1、写项目时都要加包,不要使用默认包
2、com.ji和com.ji.car这两个包没有包含关系,是两个完全独立的包,只是逻辑上看起来后者是前者的一部分。
6.4导入类import
import:如果我们需要使用其他包的类,需要使用import导入,从而可以在本类中直接通过类名来调用,否则就需要书写类的完整包名和类名。import之后,便于编写代码,提高可维护性。
package studyweek2;
//以下两种把一个包里面的某一个导入,如果要整个studyweek1导入就要使用*
import studyweek1.*;//导入studyweek1包里所有的类。
import studyweek1.study5;
import studyweek1.study6;//这个是导入studyweek1中的study6
//如果这里还要导入import studyweek2.study5,不要去记优先级,直接写全导入。
public class study2 {
public static void main(String[] args){
//如果没有使用import,就要这么使用,建议不那么写 studyweek1.study6 a=new studyweek1.study6();
study6 a=new study6();//如果在自己的包里没有找到,就会到导入的包里创建对象。
a.login();
}
}
注意1、java会默认导入java.lang包下所有的类,我们可以直接使用。
2、如果导入两个同名的类,只能用包名+类名来显示调用相关类。
静态导入:导入了某个包里的某个静态属性。
import static java.lang.Math.PI;//导入了Math包里的PI静态属性。