- 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲历亲为,详细处理每一个细节。
- 面向过程:当要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能得人,来帮我做事。
import java.util.Arrays;
public class Demo01PrintArray {
public static void main(String[] args) {
int[] array = {10,20,30,40,50}; //数组的静态初始化
//打印格式为:[10, 20, 30, 40, 50];
//面向过程 -- 每一个符号都要亲历亲为
System.out.print("[");
for (int i = 0; i < array.length; i++) {
if (i == array.length - 1) {
System.out.println(array[i] + "]");// 如果是最后一元素
} else {
System.out.print(array[i] + ", "); //如果不是最后一个元素
}
}
System.out.println("=====================");
//面向对象
//找一个JDK提供好的Arrays类
//其中有一个toString方法,直接就能把数组变成想要的格式的字符串
System.out.println(Arrays.toString(array));
}
}
- 面向对象的语言中有三大基本特性:封装、继承和多态。
什么是类?
- 类:是一组相关属性和行为的集合,可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
- 属性:该事物的状态信息。
- 行为:该事物能够做什么。
什么是对象?
- 对象:是一事物的具体体现。对象是类的一个实例,必然具备该事物的属性和行为。
定义一个student类
public class Student {
/**
* 定义一个类,用来模拟“学生”事物,其中就有两个组成部分
* 属性(是什么): 性别、年龄。。。<特征描述>
* 行为(能做什么):吃饭、睡觉、学习
*
* 对应的到java的类中
* 属性 ——》 成员变量
* String name; //姓名
* int age; //年龄
* 行为 ——》 成员方法
* public void eat(){} //吃饭 在成员方法中,static关键字要删掉
* public void sleep(){} //睡觉
* public void study(){} //学习
*/
//先写成员变量
String name; //姓名
int age; //年龄
//再写成员方法
public void eat(){}; //吃饭
public void sleep(){}; //睡觉
public void study(){}; //学习
}
注意事项:
- 1、此前的变量都叫做局部变量,都是写在方法内部的,存放在栈上一旦直接写在类里,就叫做成员变量,存放在堆上。
- 2、成员方法不要写static关键字
如何使用一个类
- 通产情况下,一给类并不能直接使用,需要根据类创建一个对象,才能使用。
- 1、导包:指出需要使用的类,在什么位置;
import 包名称.类名称
对于和当前类属于同一个包的情况,可以省略导包语句不写。
- 2、创建:格式
类型名 对象名 = new 类名称();
Student stu = new Student(); ——》 根据Student类,创建了一个名为stu的对象。
- 3、使用:分为两种情况
使用成员变量: 对象名.成员变量名
使用成员方法: 对象名.成员方法名(参数)
public class Demo02Student {
public static void main(String[] args) {
//1.导包
//此处我的Student类与我的Demo02Student处于同一个包下,所以省略导包语句不写
//2.创建
Student stu = new Student();
//3.使用对象的成员变量
System.out.println(stu.name); //默认值为null\
System.out.println(stu.age); //默认值为0
System.out.println("=====================");
//改变对象当中的成员变量数值内容
stu.name = "周"; //将右侧的字符串,赋值交给stu对象当中的name成员变量
stu.age = 23;
System.out.println(stu.name);
System.out.println(stu.age);
System.out.println("=====================");
//4、使用对象的成员方法
stu.eat();
stu.sleep();
stu.study();
}
}
- 如果成员变量没有进行赋值,那么将会有一个默认值。
手机类练习
package Class_object.demo02;
/*
定义一个类,用来模仿“手机”事物
属性:品牌、价格、颜色
行为:打电话、发短信
对应到类中
成员变量(属性)
String brand; //品牌
double price; //价格
String colour; //颜色
成员方法(行为)
public void call(String who){} //打电话
public void sendMessage(){} //群发短信
*/
public class Phone {
//成员变量
String brand; //品牌
double prince; //价格
String colour; //颜色
//成员方法
public void call(String who){
System.out.println("给" + who + "打电话");
}
public void sendMessage(){
System.out.println("群发短信");
}
}
package Class_object.demo02;
public class Demo01PhoneOne {
public static void main(String[] args) {
//根据Phone类创建一个one对象
Phone one = new Phone();
System.out.println(one.brand); //null
System.out.println(one.colour); //null
System.out.println(one.prince); //0.0
System.out.println("==============");
one.brand = "苹果";
one.colour = "红色";
one.prince = 8848;
System.out.println(one.brand);
System.out.println(one.colour);
System.out.println(one.prince);
System.out.println("==============");
one.call("周");
one.sendMessage();
}
}
- 我们通过画图来清晰的看到类在内存空间中是如何运作的
- 一个对象的内存图
- 另外还有两种情况
- 1、两个对象使用同一个方法的内存图
- 2、两个引用指向同一个对象的内存图(两个对象引用指向同一个对象空间)
既然任何数据类型都能作为方法的参数或返回值,那么能否用自定义的Phone这个类作为方法的参数类型?
- 自定义的类最为方法的参数
public static void main(String[] args) {
Phone one = new Phone();
one.brand = "苹果";
one.price = 8848.0;
one.colour = "白色";
//我现在有“苹果”这样一个手机叫做one,我能否将它作为一个参数往method的方法中进行传递?
method(one); //one当中是一个地址值
}
public static void method(Phone param){ //这里param收到的也是一个地址值
System.out.println(param.brand);
System.out.println(param.price);
System.out.println(param.colour);
}
- 自定义的类作为方法的返回值
- 当使用一个对象类型作为方法的返回值时,返回值其实就是对象的地址值。
public static void main(String[] args) {
Phone two = getPhone();
System.out.println(two.brand);
System.out.println(two.price);
System.out.println(two.colour);
}
public static Phone getPhone(){
Phone one = new Phone();
one.brand = "苹果";
one.price = 8848;
one.colour = "蓝色";
return one; //谁调用了getPhone,就把one的地址交给谁
}
成员变量和局部变量的区别
- 1、定义的位置不一样:局部变量在方法的内部;成员变量在方法的外部,直接写在类当中。
- 2、作用范围(作用域)不一样:局部变量只在方法当中可以使用,出了方法就不能用了;成员变量是在类当中,整个类都可以使用。
- 3、默认值不一样:局部变量没有默认值,想要使用,必须进行初始化赋值;成员变量未赋值时会有默认值。
- 4、内存位置不一样:局部变量位于栈内存;成员变量位于堆内存
- 5、生命周期不一样:局部变量随着方法进栈而诞生,随着方法出栈而消失;成员变量随着对象创建而诞生,随着对象被垃圾回收而消失。(垃圾回收是指,这个对象再也没有用处时,JVM会在合适时机将其清理掉,垃圾回收的时机java程序员是无法直接控制的)
private关键字的作用及使用(直接访问/间接访问)
- 当定义Person的年龄时,无法阻止不合理的值被设置进来
public class Person {
String name; //姓名
int age; //年龄
public void show(){
System.out.println("我叫," + name + ",年龄:" + age);
}
}
public class Demo03Person {
public static void main(String[] args) {
Person person = new Person();
person.show();
person.name = "周";
person.age = -4; //此时会打引出来 我叫,周,年龄:23
//但这不符常理,因为年龄并不能为负,但是我们在定义Person类中的age时使用的是int,所以允许任何整数
}
}
- 要解决这个问题,使用关键字private关键字将需要保护的成员变量进行修饰
public class Person {
String name; //姓名
private int age; //年龄
public void show(){
System.out.println("我叫," + name + ",年龄:" + age);
}
}
- 一旦使用了private进行修饰,那么本类当中仍然可以随意访问,但超出了本类范围之外就不能再直接访问即
person.age
这种访问方法在Person
这个类里可以使用但在Demo03Person
这个类里无法使用。 - 既然无法直接访问,就需要进行间接访问
- 间接访问private成员变量,就是定义一对getter/setter方法
public class Person {
String name; //姓名
private int age; //年龄
public void show(){
System.out.println("我叫," + name + ",年龄:" + age);
}
//成员方法专门用于向age设置数据
public void setAge(int num){
if(num < 100 && num >= 0){
age = num;
}else{
System.out.println("数据不合理");
}
}
//成员方法专门用于获取age的数据
public int getAge(){
return age;
}
}
public class Demo03Person {
public static void main(String[] args) {
Person person = new Person();
//person.show();
person.name = "周";
//person.age = -4; //直接访问private内容,是错误写法
person.setAge(-24);
}
}
- 注意:对于getter/setter方法名称必须遵守
getxxx/setxxx
命名规则,且对于getter方法来说,不能有参数,返回值类型和成员变量对应;对于setter来说,不能有返回值,参数类型和成员变量对应 - 对于基本类型当中的boolean类型,getter要写成
isxxx
的格式!!!
//boolean类型的getter//setter方法略有不同
public void setMale(boolean b){
male = b;
}
public boolean isMale(){
return male;
}
public class Demo04Student {
public static void main(String[] args) {
Student stu = new Student();
stu.setMale(true);
System.out.println(stu.isMale());
}
}
this关键字的作用
- 当方法的局部变量和类成员变量重名的时候,根据“就近原则,优先使用局部变量”
- 如果需要访问本类当中的成员变量,需要使用关键字
this.成员变量名
public class Person {
String name;
public void sayHello(String name){
System.out.println(name + ", 你好,我是" + this.name);
}
}
- 通过谁调用的方法,谁就是
this
。
构造方法
-
构造方法是专门用来创建对象的方法,当我们通过关键字
new
来创建对象时,其实就是在调用构造方法 -
格式:
-
public 类名称(参数类型 参数名称){方法体}
-
注意事项:
-
- 1、构造方法的名称必须和所在的类名称完全一样,大小写也要相同
-
- 2、构造方法不要写返回值类型,
void
也不要写
- 2、构造方法不要写返回值类型,
-
- 3、构造方法不能return一个具体的返回值
-
- 4、如果没有编写任何构造方法,编译器将会默认赠送一个构造方法没有参数,方法体什么事情都不做
-
- 5、一旦编写了至少一个构造方法,那么编译器将不再赠送
-
- 6、构造方法也是可以进行重载的
public class Student {
//成员变量
private String name;
private int age;
//无参数的构造方法
public Student(){
System.out.println("无参构造方法执行了");
}
//重载
//全参数的构造方法
public Student(String name, int age){
System.out.println("全参构造方法执行了");
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
public class Demo02Student {
public static void main(String[] args) {
Student stu1 = new Student(); //无参构造
System.out.println("================");
Student stu2 = new Student("周",23); //全参构造
System.out.println("姓名" + stu2.getName() + ", 年龄," + stu2.getAge());
//如果需要改变对象当中的数据内容,仍然还需要使用stexxx方法
stu2.setAge(24);
System.out.println("改变年龄");
System.out.println("姓名" + stu2.getName() + ", 年龄," + stu2.getAge());
}
}
综合练习:如何定义一个标准的学生类
一个标准的类,通常要满足下面四个组成部分
- 1、所有的成员变量都要使用private关键字修饰
- 2、为每一个成员变量编写一对Getter/Setter方法
- 3、编写一个无参数构造方法
- 4、编写一个全参数构造方法
一个标准的类也叫做Java Bean
- 我们在新建一个类的时候,只需要写好它的成员变量,之后通过快捷键
alt + inster
在菜单里可以选择自动生成Getter/Setter方法和无/全参构造方法
通过习题了解一些详细概念
1、阅读如下代码。请问,对语句行test.hello()
,描述正确的有:
package NowCode;
class Test{
public static void hello(){
System.out.println("hello");
}
}
public class MyApplication{
public static static void main(String[] args){
Test test = null;
test.hello();
}
}
- A、编译能通过,并正确运行
- B、以你为使用了未初始化的变量,所以不能编译通过
- C、以错误的方式访问了静态方法
- D、能编译通多,但因变量为null,不能正常运行
解析:此处正确答案为A,编译能通过,并正确运行,我们首先看main函数处,Test test = null
这段语句表示new一个test不指向任何对象(空对象),所以如果此时我们使用test.
来调用的话会出现空指针异常即NullPointerException
,但在此题中,我们这里在Test类中写的hello方法为static
类型,这样此hello方法就不依赖于对象,可以通过类直接调用。 重点:静态方法不依赖于对象。
2、以下代码的运行结果是:
public static void main(String[] args){
String s;
System.out.println("s=" + s);
}
解析:结果为:由于String s 没有初始化,代码不能编译通过 。
3、如下代码会编译报错的原因是什么?
public class Test {
public int aMethod(){
static int i = 0;
i++;
return i;
}
public static void main(String args[]){
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
解析:静态的变量是不依赖于对象的,但此处aMethod
方法的调用是需要引用new一个对象,所以static int i = 0
是不能放在此处的。若将方法改成public static int aMethod()
,则此处依然为报错,但此时是因为,i是定义在方法里面,属于局部变量,局部变量是存放在栈上的,而static
存放的变量是在方法区,所以此处冲突。
4、编译运行下面代码,会出现什么情况?
public class Pvf{
static boolean Paddy;
public static void main(String args[]){
System.out.println(Paddy);
}
}
解析:定义了一个静态类型的Boolean类型变量,同时输出它。此处的Paddy属于类变量。所以会编译通过并输出结果false。
5、已知如下类,那些使用是正确?
public class Test{
private float f=1.0f;
int m = 12;
static int n = 1;
public static void main(String args[]){
Test t = new Test();
}
}
- A、t.f = 1.0
此处不能这样使用,因为应该写为t.f = 1.0f - B、this.n
n是一个静态的,this表示的是当前对象的引用,所以不能调用n - C、Test.m
通过类名调用,除非m是静态时,才可以访问 - D、Test.n
6、以下程序代码的说明正确的是?
public class HasStatic{ //1
private static int x = 100; //2
public static void main(String args[]){//3
HasStatic hsl = new HasStatic(); //4
hsl.x++; //5
HasStatic hs2 = new HasStatic(); //6
hs2.x++; //7
has1 = new HasStatic(); //8
hs1.x++; //9
HasStatic.x--; //10
System.out.println("x =" + x); //11
}
}
- A、程序通过编译,输出结果为:x=102
- B、程序通过编译,输出结果为:x=103
- C、10行不能通过编译.因为x星私有静态变量
- D、5行不能通过编译.因为引用了私有静态变量
解析:x是静态变量 。
7、在JAVA中,假设A有构造方法A(int a),则在类A的其他构造方法中调用该构造方法和语句格式应该为()
- A.this.A(x)
- B.this(x)
- C.super(x)
- D. A(x)
解析:在类A的其他构造方法中调用该构造方法只能用this,this有三种用法:1、访问数据this.data
;2、访问普通方法this.func()
;3、调用它的构造方法this()