1. 面向对象
1.1. 基本概念
什么是对象?
你能看到的万事万物,都是对象,比方说桌子,电脑,水杯…..。”万物皆对象。”
什么是面向对象?
面向对象简称 OO(Object Oriented),一种编程思想。面向对象编程,简称OOP(Object Oriented Programming)。抽象出思维,不再是线性的思维方式。
举例:大象装冰箱。 线性的思维:打开冰箱门,装进大象,关上冰箱门。一系列的动作,有先后,顺序发生的。 面向对象对象思维: 抽象出3个类,1个类大象 ,搞清楚大象
有哪些静态特征,哪些动态的行为(进入冰箱),1个类 冰箱 ,分清有哪些静态特征,哪些动态行为(开门,关门), 操作类(测试类),组合大象,和冰箱,实现功能。
面向对象和面向过程有什么区别?
面向对象:盖浇饭 ,盖菜和饭分离,菜饭分离---à不喜欢盖菜,可以剥掉,重新加。面向对象通过3大特征,提供大范围大面积的解决思路。
面向过程:蛋炒饭 ,米饭盒鸡蛋混合在一起,--à不喜欢鸡蛋,只能倒掉,重新做。面向过程提供小面积的解决思路
面向对象:纪传体(各个人物分散,比方说史记),面向过程:编年体(按时间先后 ,资治通鉴)
炒饭好还是盖饭好?结论是各有所长。
从饭馆的角度,肯定是盖饭有优势,盖菜和饭分离,可以自由组合,不会造成浪费。从软件工程术语的角度,炒饭,饭盒鸡蛋混合,耦合度太高,可维护性差。盖饭,菜饭分离,耦合度低,可维护性好。
为什么要面向对象?
因为人类的思维有限,只有面向对象,才能为我们提供更广阔的思维方式,通过面向对象的“封装”,”继承”,“多态”可以提供大面积大范围的解决思路,用于构建大型系统。
为什么人类的智力会不够用?
1个班长管理30个人,ok,1个校长管理1000个人,需要设置班主任 。1个县长,管理100万个人,需要下设局长,区长,镇长。1个省长,管理1个市,控制市长。1个总理,管理一个国家,控制省长,各个部长。发现,随着管理范围的扩大,人的智力越来越不够用。需要下设组织机构。
Java中都是以类为组织结构的,比方说学生类 Student类 ,部门类 ,Department类。
类:类是抽象的,从对象中 抽取出一些静态特征(属性)和动态行为(方法)封装而成的。狗狗类:Dog类 。类是模板(类是对象的集合),类是对象的类型,一个类可以有无数个对象。
对象: 具体的一个对象。张三家的一条黑狗 . 对象是类的一个具体的实例。一个对象,也叫一个实体。
Java中什么叫面向对象? 面向对象是一种编程思想。Java是以类为组织结构的,类又是封装了相同的属性和方法的集合,看成是对象的模板。
Java有3大特性“封装”“继承”“多态”,通过这3大特性,可以提供大面积的解决思路,可以用于构建大型系统。
1.2. 方法声明、传值、返回
什么是方法? 定义在类中,用于描述一个类的动态的行为,说明一个类的功能的。
如何声明一个方法
注意:同一个类中,方法不允许重名(不能定义一个一模一样(返回值类型,访问修饰符,方法名,参数列表都相同)的方法)
如何在main方法内调用一个方法:
先实例化获取对象 ,对象名.方法名 。注意调用无返回值和带返回值的方法的区别。无返回值的方法,直接对象名.方法名调用,带返回值的方法,需要用一个和方法返回值类型相匹配的变量来接收。
方法如何传值?
定义带参方法,多个参数之间,用逗号相隔。
调用时要加上参数
例题:
package com.njwb.methoduse;
/**
* 访问修饰符 返回值类型 方法名(参数列表){
*
* }
* 无返回值的无参方法 public void showNum()
* 带返回值的无参方法 publicint getNum()
* 无返回值的带参方法 public void addNum(int a,int b)
* 带返回值的带参方法 publicint getTwoNumSum(int a,int b)
* @author Administrator
*
*/
public class Demo {
/**
* 无返回值的
*/
public void showNum(){
System.out.println("num="+10);
}
/**
* 带返回值的方法
* return 具体的值;
* 值的类型必须和 方法声明的时候的返回值类型一致。
* @return
*/
public int getNum(){
return 20;
}
/**
* 方法不能一模一样
* @return
*/
/*public int getNum(){
return 30;
}*/
/**
* 带返回值的
*/
public String getName(){
return "hello";
}
/**
* 计算2个数的和
* @param a
* @param b
*/
public void addNum(int a,int b){
System.out.println("两数之和为:"+(a+b));
}
/**
* 带返回值的带参方法
* @param a
* @param b
* @return
*/
public int getTwoNumSum(int a,int b){
return a+b;
}
}
package com.njwb.methoduse;
public class DemoApp {
public static void main(String[] args) {
Demo d = new Demo();
System.out.println("-----------------调用无参方法------------------------");
//不带返回值的
d.showNum();
//如何调用带返回值的方法?要用一个和方法返回值类型相匹配的变量来接收 ,这个变量的类型可以(取值范围)大于等于方法的返回值的类型
//getNum()方法 返回int类型,可以用int接收,float,double接收 不能用short,byte来接收
int num1 = d.getNum();
System.out.println(num1);
double num2 = d.getNum();
System.out.println(num2);
//编译错误
//short num3 = d.getNum();
String str = d.getName();
System.out.println(str);
System.out.println("-----------------调用带参方法------------------------");
d.addNum(10, 12);
int sum = d.getTwoNumSum(3, 4);
System.out.println("两数之和为:"+sum);
}
}
练习:
编写一个方法,方法的作用是循环输出0~X,X是通过参数传入方法的。在main方法从控制台接收一个数字,然后作为参数传入这个方法。
方法的返回值
语法:return 要返回的值;
同时修改void为返回值的类型
调用时的参数要对应,如果接收两个参数,就必须在调用时输入两个参数
练习:
(1)编写一个方法,方法接收3个参数,分别是姓名、年龄、性别,该方法在控制台输出这三个参数。在main方法调用该方法,将小明、18、男作为参数传入该方法。
(2)编写一个方法,方法接收3个参数,分别是三门课程的成绩,该方法计算三门课的平均分后,返回平均分。在main方法分三次接收控制台输入的三门课的成绩,传入该方法并输出返回值。
public class Demo2 {
/**
* 循环输出0--x
* @param x 形参
*/
public void showNum(int x){
System.out.println("0到"+x+"遍历如下:");
for(int i=0;i<=x;i++){
System.out.println(i);
}
}
/**
* 无返回值的带参方法,用于显示传入的3个变量的值
* @param name
* @param age
* @param sex
*/
public void showInfo(String name,int age,String sex){
System.out.println("个人信息如下:\n姓名:"+name+",年龄:"+age+",性别:"+sex);
}
/**
* 带返回值的带参方法 ,用于返回输入的3个变量的值
* @param name
* @param age
* @param sex
* @return
*/
public String getInfo(String name,int age,String sex){
return "个人信息如下:\n姓名:"+name+",年龄:"+age+",性别:"+sex;
}
/**
* 带返回值的带参方法 ,返回3个参数的平均值
* @param num1
* @param num2
* @param num3
* @return
*/
public double calAvg(double num1,double num2 ,double num3){
return (num1+num2+num3)/3;
}
}
import java.util.Scanner;
public class Demo2App {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("------------练习1-----------------");
//1.实例化
Demo2 d = new Demo2();
/*
System.out.print("请输入想要遍历的数字:");
int num = input.nextInt();
//2.调用方法 num 实参
d.showNum(num);*/
System.out.println("------------练习2-----------------");
//d.showInfo("小明", 18, "男");
/*System.out.print("请输入姓名:");
String name = input.next();
System.out.print("请输入年龄:");
int age = input.nextInt();
System.out.print("请输入性别:");
String sex = input.next();
//调用带参方法,传入参数
d.showInfo(name, age, sex);
//如果是带返回值的方法
String str = d.getInfo(name, age, sex);
System.out.println(str);*/
System.out.println("------------练习3-----------------");
//定义一个长度为3的 ,double类型的数组
double[] scoreArr = new double[3];
//接收3门成绩
System.out.print("请输入第1门成绩:");
scoreArr[0] = input.nextDouble();
System.out.print("请输入第2门成绩:");
scoreArr[1] = input.nextDouble();
System.out.print("请输入第3门成绩:");
scoreArr[2] = input.nextDouble();
//调用方法
double avg = d.calAvg(scoreArr[0], scoreArr[1], scoreArr[2]);
System.out.println("3个数的平均值为:"+avg);
}
}
1.3. 方法的重载(Overload)重点
Java允许方法重名,主要参数不同就可以,参数不同包括数据类型不同、参数个数不同、不同类型的参数顺序不同。(重载和返回值类型,访问修饰符无关)
注意:数据类型不同,可以不考虑参数的个数,如果参数个数不同,可以不考虑类型。
/**
什么是方法的重载?
* 重载必须在同一个类里,方法名要相同
*
* 3个条件至少满足一样
* 1.参数的个数不同
* 2.参数的类型不同
* 3.不同类型的参数的顺序不同
*
* 和访问修饰符,返回值类型无关(访问修饰符,返回值类型可以不同)。
* @author Administrator
*/
public class Demo {
/**
* 方法1
* 返回2个数的和
* @param a
* @param b
* @return
*/
public int addNum(int a,int b){
return a+b;
}
/**
* 方法2
* 参数个数不同 ,是重载
* @param a
* @param b
* @param c
* @return
*/
public int addNum(int a,int b,int c){
return a+b+c;
}
/**
* 方法3,也是重载,相对于方法1而言,参数的类型不同
* @param a
* @param b
* @return
*/
public double addNum(double a,int b){
return a+b;
}
/**
* 方法4,和方法3重名,只是参数的名字不同而已,参数类型相同
*/
/*public double addNum(double b,int a){
return a+b;
}*/
/**
* 方法5,相对于方法3而言,只是访问修饰符不同,不是重载,方法的重名
*/
/*private double addNum(double a,int b){
return a+b;
}*/
/**
* 方法6,和方法3重名,只是返回值类型不同,不是重载
*/
/*public int addNum(double a,int b){
return (int)(a+b);
}*/
/**
* 方法7相对于方法3,方法1,而言,不同类型的参数的顺序不同 是重载,相对方法2而言,还是重载,个数不同,类型也不同
*/
public double addNum(int b,double a){
return a+b;
}
}
面试题:什么是方法的重载,什么是方法的重写? 有什么区别。
练习:
编写三个方法名字都叫add,分别支持接收1个整数,2个整数,3个整数,每个方法的功能都是在控制台输出传入整数的总和。在main方法中分别调用这三个方法测试是否能够正常输出。
public class Demo2 {
public int addNum(int a){
return a;
}
public int addNum(int a,int b){
return a+b;
}
public int addNum(int a,int b,int c){
return a+b+c;
}
public static void main(String[] args) {
Demo2 d = new Demo2();
int sum1 = d.addNum(10);
int sum2 = d.addNum(12,13);
System.out.println(sum1);
System.out.println(sum2);
System.out.println(d.addNum(1, 3, 9));
}
}
1.4. 类声明、实例化、调用
如何声明一个类:
public class 类名 {
}
类下一层有什么?
(1) 很多属性(成员变量、字段)
(2) 很多方法(函数)
如何调用类中的方法?
对象名.方法名调用 p.showName();
如何在类中写多个属性和方法?
写属性: 访问修饰符 类型 属性名(=初始值) public String name(=“jack”);
写方法:
访问访问修饰符 返回值类型 方法名(参数列表){
方法体
}
Public void showName(){
System.out.println(“姓名是:”+name);
}
如何调用不同的方法? P.showName() ; p.showAge();
如何访问不同的属性? 对象名.属性名 p.name ,p.age,
注意:1.不考虑内部类的情况下,1个.java文件中只能出现1个public修饰的类,该类的类名和.java的文件名相同,可以出现多个不用public修饰(没有修饰符,用default修饰)的类。
2.void 表示这个方法没有返回值
练习:
新建一个Person类,声明三个属性,分别是姓名、年龄、性别。在Person类中编写三个方法showName、showAge、showSex,作用分别是在控制台输出姓名、年龄、性别。在main方法中实例化Person类,调用showName方法。
package com.njwb.classuse;
/**
* 1.有3个属性
* 2.有3个方法
* @author Administrator
*
*/
public class Person {
public String name="jack";//姓名
public int age=10;//年龄
public String sex="男";//性别
/**
* 显示名字
*/
public void showName(){
System.out.println("名字是:"+name);
}
/**
* 显示年龄
*/
public void showAge(){
System.out.println("年龄是:"+age);
}
public void showSex(){
System.out.println("性别是:"+sex);
}
}
package com.njwb.classuse;
/**
* Person类的测试类
* 1.实例化(创建Person类的对象)
* 2.给属性赋值
* 3.调用方法
* @author Administrator
*
*/
public class TestPerson {
public static void main(String[] args) {
//1实例化 创建Person类的对象p
Person p = new Person();
//2.给属性赋值
p.name = "张三";
p.age = 18;
p.sex = "男";
//3.调用方法,显示信息
p.showName();
p.showAge();
p.showSex();
}
}
实例化后给属性赋值
状态->属性
行为->方法
如:
文件 属性:大小、创建日期等 方法:复制、剪切、粘贴
人 属性:身高、体重、年龄 方法:打招呼、喊叫、走路
狗狗 属性:品种 ,体重 名字 方法:会叫,会跑 ,会咬人 ,会抓飞碟
练习:
(1) 新建一个学校类,声明一些属性,至少包括学校名称、教室数量、老师数量。编写一个方法,输出这三个变量的值。
public class School {
public String schoolName; //学校名字
public int roomCount;//教室数量
public int teacherCount;//老师的数量
/**
* 该方法用于显示3个属性的信息
*/
public void showInfo(){
System.out.println("学校名称:"+schoolName+",教室数量:"+roomCount+",老师数量:"+teacherCount);
}
}
/**
* 测试类 sch,sch2:具体的1个对象 School:类 ,1个类可以new出无数个对象
* @author Administrator
*
*/
public class TestSchool {
public static void main(String[] args) {
//1.实例化
School sch = new School();
//2.给属性赋值
sch.schoolName = "南j";
sch.roomCount = 20;
sch.teacherCount = 50;
//3.调用方法显示信息
sch.showInfo();
School sch2 = new School();
//2.给属性赋值
sch2.schoolName = "南京大学";
sch2.roomCount = 20;
sch2.teacherCount = 50;
//3.调用方法显示信息
sch2.showInfo();
}
}
(2) 新建一个狗类,声明一些属性,至少包括名称、品种、年龄、性别。编写一些方法,至少包含喊叫和抓飞盘。
public class Dog {
public String name; //名称
public int age;//年龄
public String sex;//性别
public String strain;//品种
/**
* 叫的方法
*/
public void cry(){
System.out.println(name+"在喊叫");
}
/**
* 抓飞碟
*/
public void catchFlyingDisc(){
System.out.println(name+"在抓飞碟");
}
/**
* 宠物的自白 ,显示狗狗信息
*/
public void print(){
System.out.println("宠物的自白:\n我是一只"+strain+",我叫"+name+",我的年龄是:"+age+",我的性别是:"+sex);
}
}
public class TestDog {
public static void main(String[] args) {
//1.实例化
Dog dog = new Dog();
//2.给属性赋值
dog.name = "旺财";
dog.age = 1;
dog.sex = "雄";
dog.strain = "拉布拉多犬";
//3.通过对象名.方法名()调用方法
dog.print();
dog.catchFlyingDisc();
dog.cry();
}
}
1.5. 变量的作用域
变量可以写在哪里? 类里或者方法里
什么是成员变量? 定义在类里的
什么是局部变量? 定义在方法中(语句块中)的
成员变量和局部变量的区别(作用范围/默认值)
成员变量 :属性,定义在类里的,整个类都可以访问。
局部变量:定义在方法中,或者语句块中,只在本方法内或者本语句块中有效
成员变量默认初始化值
如果是基本数据类型,那么默认值是基本数据类型对应的值,比方说
int ------à0 ,double----à 0.0d, float -----à0.0f; long----à0L; char--à ‘\u0000’ byte-à0 short-à0 boolean-----àfalse
如果是引用数据类型,那么默认值是null ,比方说
如果没有分配内存 int[] arr ----ànull ,
如果分配内存(int[] arr = new int[3])数组默认值--à对应的内存地址, 每一个元素默认值是0
如果没有分配内存 String[] ----ànull ,
如果分配内存(String[] arr = new String[3]) 数组默认值--à对应的内存地址,每一个数组元素的默认值 null
局部变量的优先级更高,如果出现同名的局部变量和成员变量
例题:
/**
* 属性/成员变量,测不同类型的成员变量的默认值
* 局部变量:
* @author Administrator
*
*/
public class Demo {
//成员变量
public String name="tom";
public int age;
public char sex;
public double score;
public float score2;
public boolean flag;
public int[]arr;
public String[] arr2;
//注意
public int[]arr3 = new int[3];
public String[] arr4 = new String[3];
public void showInfo(){
int num = 10;
System.out.println("num="+num);
//局部变量name和成员变量name同名,这个时候,局部变量拥有更高的优先级,此处打印的bob
String name ="bob";
System.out.println("name="+name);
}
public void ceshi(){
//System.out.println("num="+num);
//打印的tom,name指的的成员变量,该成员变量在整个类中都可以访问。
System.out.println("name="+name);
}
}
package com.njwb.classuse;
public class TestDemo {
public static void main(String[] args) {
//1.实例化
Demo d = new Demo();
//2.访问属性
System.out.println("String类型的默认值:"+d.name);
System.out.println("int类型的默认值:"+d.age);
System.out.println("char类型的默认值:"+d.sex);
System.out.println("double类型的默认值:"+d.score);
System.out.println("float类型的默认值:"+d.score2);
System.out.println("boolean类型的默认值:"+d.flag);
System.out.println("int[]类型的默认值:"+d.arr);
System.out.println("String[]类型的默认值:"+d.arr2);
//分配长度 ,开辟了空间,此处打印的是int[] arr3对应的内存地址 ,String[] arr4对应的内存地址
System.out.println("分配长度后的int[]类型的默认值:"+d.arr3+",下标为0的元素:"+d.arr3[0]);
System.out.println("分配长度后的String[]类型的默认值:"+d.arr4+",下标为0的元素:"+d.arr4[0]);
System.out.println("--------------------");
//调用方法
d.ceshi();
System.out.println("--------------------");
d.showInfo();
}
}
1.6. 方法的修饰符(重点)
访问修饰符 | 本类 | 本包不同类 | 本包中的子类 | 其他包的子类 | 其他包的其他类 |
private | Ok | No | No | NO | NO |
default(表现形式就是什么都不写) | Ok | ok | ok | no | no |
protected | ok | ok | ok | ok | NO |
public | ok | ok | ok | ok | ok |
总结:
Private 修饰的,只限于本类有效
default修饰的 只限于本包内有效 ,其他包不管是不是子类都无法访问
Protected修饰的 本包有效 ,其他包的子类有效(不管子类在不在同一个包下,protected修饰的都能访问)
Public 修饰的 本项目中的任何地方都能够访问,不管在不在同一个包下
访问级别 private<default<protected<public ,访问权限private最严格。
4个访问修饰符修饰属性,修饰方法,作用域都是一样的。
导包:在一个包下,如果想访问另一个包下的类中的方法,需要先导包。比方说com.njwb.modifiertest02包下有个TestPerson类,想访问com.njwb.modifiertest包下的Person类中的ceshi()方法
那么在TestPerson类中需要,需要在开头import com.njwb.modifiertest.Person 表示导入该包下的该类 ,或者 import com.njwb.modifiertest.*;表示导入该包下的所有的类。 导包的快捷键
1.7. 如何更改工程的编码格式
1. 改当前选中工程的编码 选中工程---右击 --properties ----Resource----Text file encoding------Other UTF-8 -- apply–ok.
2. 选中工程 ---菜单栏Project----Resource---Text file encoding-----Other: UTF-8 ---apply–ok.
3. Window--àPreferences ----à左上角---搜索栏 输入wokspaces-----选中Workspace --àText file encoding----Other UTF8 ---apply—ok