面向过程与面向对象
Java基本元素:类、对象
类是抽象,类实例化后就是对象(又叫实例)。
对象的创建与使用
创建类的对象 = 类的实例化 = 实例化类
public class PersonTest {
public static void main(String[] args) {
// 2. 创建类对象
Person p1 = new Person();
// 3. 调用对象的方法和属性
p1.name="tony";
p1.age=48;
p1.eat();
p1.speak("Chinese");
Person p2 = new Person();
System.out.println(p2.name); //null
}
}
// 1. 创建类,设计类的成员
class Person{
// 属性
String name;
int age=1;
// 方法
public void eat(){
System.out.println("人喜欢吃猫肉");
}
public void speak(String language){
System.out.println("人可以说"+language);
}
}
内存解析
对象的内存解析
类的成员之一:属性
类的成员之二:方法
对象数组
Student.java
public class Student {
int number;
int state;
int score;
}
StudentTest.java
public class StudentTest {
public static void main(String[] args) {
// 声明Student类型的数组
Student[] stus =new Student[20];
// 给元素赋值
for (int i=0;i<20;i++) {
stus[i] = new Student();
// 给Student对象赋值
stus[i].number = i + 1;
stus[i].state = (int) (Math.random() * 6 + 1);
stus[i].score = (int) (Math.random() * 90 + 10);
System.out.println("原始学生信息,学号:" + stus[i].number + ",年级:" + stus[i].state + ",成绩:" + stus[i].score);
}
//学生排序
for (int i=0;i<stus.length;i++){
for (int j=0;j<stus.length-i-1;j++){
if (stus[j].score>stus[j+1].score){
//如果需要换序,交换的是数组的元素:Student对象
Student temp = stus[j];
stus[j] = stus[j+1] ;
stus[j+1]= temp;
}
}
}
System.out.println("----------");
for (int i=0;i<20;i++) {
System.out.println("排序后的学生信息,学号:" + stus[i].number + ",年级:" + stus[i].state + ",成绩:" + stus[i].score);
}
}
}
对象数组内存解析
JVM内存结构
理解万事万物皆对象
对象数组的内存解析
匿名对象
public class InstanceTest {
public static void main(String[] args) {
// 有名的对象 有名,p
Phone p = new Phone();
System.out.println(p);
p.sendEmail();
p.playGame();
p.showPrice();
// 匿名对象
// 每new一次是不同的一个对象
new Phone().price=1999;
new Phone().showPrice();// 0.0
// 匿名对象在开发中的使用
PhoneMall mall = new PhoneMall();
// 给phone赋值了:new Phone()
mall.show(new Phone());
}
}
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.playGame();
}
}
class Phone{
double price;//价格
public void sendEmail(){
System.out.println("发送邮件");
}
public void playGame(){
System.out.println("打游戏");
}
public void showPrice(){
System.out.println("手机价格为:"+price);
}
}
自定义数组工具类
ArraysUtil.java
package com.company.day09;
public class ArraysUtil {
// 数组最大值
public int getMax(int[] arr){
int max = arr[0];
for (int i=1;i<arr.length;i++){
if (arr[i]>max){
max = arr[i];
}
}
return max;
}
// 数组最小值
public int getMin(int[] arr){
int min = arr[0];
for (int i=1;i<arr.length;i++){
if (arr[i]<min){
min = arr[i];
}
}
return min;
}
// 数组元素总和
public int getSum(int[] arr){
int sum=0;
for (int i=0;i<arr.length;i++){
sum=sum+arr[i];
}
return sum;
}
// 数组的平均值
public double getAvg(int[] arr){
double avg = getSum(arr)/(arr.length/1.0);
return avg;
}
// 反转数组
public int[] getRevArr(int[] arr){
for(int i=0;i<arr.length/2;i++){
int temp=arr[i];
arr[i]=arr[arr.length-i-1];
arr[arr.length-i-1]=temp;
}
return arr;
}
// 复制数组
public int[] copyArr(int[] arr){
int[] newArr = new int[arr.length];
for (int i=0;i<arr.length;i++){
newArr[i]=arr[i];
}
return newArr;
}
// 数组排序
public int[] sortArr(int[] arr){
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length-1-i;j++){
if (arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
// 查找制定元素
public int search(int[] arr,int target) {
int index = -1;//标识是否找到,未找到为-1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
index = i;
}
}
return index;
}
}
ArraysUtilTest.java
package com.company.day09;
import java.util.Arrays;
public class ArraysUtilTest {
public static void main(String[] args) {
ArraysUtil util =new ArraysUtil();
int[] arr = new int[]{1,2,9,4,12,6};
int max= util.getMax(arr);
int min= util.getMin(arr);
int sum= util.getSum(arr);
double avg= util.getAvg(arr);
// 反转数组
int arr1[]= util.getRevArr(arr);
// 复制数组
int arr2[] = util.copyArr(arr);
// 数组排序
int arr3[] = util.sortArr(arr);
// 搜索元素
int index = util.search(arr,12);
System.out.println(max);
System.out.println(min);
System.out.println(sum);
System.out.println(avg);
System.out.println(Arrays.toString(arr1));
System.out.println(Arrays.toString(arr2));
System.out.println(Arrays.toString(arr3));
System.out.println(index);
}
}
再谈方法
- 方法的重载
练习:
public class OverloadTest {
public static void main(String[] args) {
OverloadTest ovl = new OverloadTest();
System.out.println(ovl.compute(3));
System.out.println(ovl.compute(3,10));
ovl.compute("重载好像不难");
System.out.println(ovl.getMax(3,9));
System.out.println(ovl.getMax(3.1,3.2));
System.out.println(ovl.getMax(9.9,12.1,17.5));
}
public int compute(int num){
return num*num;
}
public int compute(int num1,int num2){
return num1*num2;
}
public void compute(String str){
System.out.println(str);
}
public int getMax(int num1, int num2){
return (num1>num2?num1:num2);
}
public double getMax(double num1, double num2){
return (num1>num2?num1:num2);
}
public double getMax(double num1, double num2,double num3){
return (num3>(num1>num2?num1:num2))?num3:(num1>num2?num1:num2);
}
}
- 可变形参的方法
- 方法参数的值传递机制(重点)
main方法调用的sout(m,n)和swap方法调用的sout(m,n)不一样。swap方法调用完之后,就会销毁掉m,n,temp。
import java.util.Arrays;
public class ExeTest {
public static void main(String[] args) {
int[] arr = new int[]{12,3,3,34,56,77,432};
int[] arr1 = new int[arr.length];
for (int i=0;i<arr.length;i++){
arr1[i] = arr[i]/arr[0];
}
System.out.println(Arrays.toString(arr1));
}
}
- 递归方法
OPP特征之一:封装与隐藏
- 封装性的体现
public class AnimalTest {
public static void main(String[] args) {
Animal an =new Animal();
an.age=10;
an.legs=-4;
an.show();
}
}
class Animal{
int age ;
String name;
int legs;
public void show(){
System.out.println("动物的年纪:"+age+",动物的脚:"+legs);//动物的年纪:10,动物的脚:-4
}
}
可以随意修改legs的数字,只能限定为int型,但实际legs应为正整数。
给legs声明为私有变量,提供一个方法setLegs()去修改legs,方法中增加对这个变量的限制条件。除了修改属性的值,还需要提供getLegs()获取到属性的值。
public class AnimalTest {
public static void main(String[] args) {
Animal an =new Animal();
an.age=10;
// an.legs=-4; 不能直接使用 an.legs调用了。需要调用setLegs方法
// an.setLegs(-4); 应该会报错,但是还没学。
an.setLegs(4);
int legs = an.getLegs();
System.out.println(legs);
an.show();
}
}
class Animal{
int age ;
String name;
private int legs;//给属性legs声明为私有权限,使legs对外不可见。
// 要修改legs,需要调用setLegs。方法中添加对legs修改时的限制条件
public void setLegs(int l){
if (l>0&&l%2==0){
legs=l;
}else {
legs=0;//标记错误
System.out.println("抛出异常,还没学");
System.out.println("legs错误");
}
}
// 可以修改,也要可以获取,要获取legs,调用getLegs获取
public int getLegs(){
return legs;
}
public void show(){
System.out.println("动物的年纪:"+age+",动物的脚:"+legs);//动物的年纪:10,动物的脚:-4
}
}
封装性的体现就是将类的属性私有化,同时提供公共(public)的setXXX来设置属性,提供公共(public)的getXXX方法来获取属性。set是没有返回值的,get是有返回值的。
- 权限修饰符
类的成员之三:构造器(或构造方法、constructor)
-
构造器的作用
创建对象、给对象进行初始化。
-
构造器说明
public class PersonTest {
public static void main(String[] args) {
// 创建类的对象
// 变量类型 变量名 = new 一个对象 -->Person()就是构造器
// 构造器与类同名
Person p = new Person();
p.eat();
// 使用有参数的构造器创建对象
Person p1 = new Person("tom");
// 构造器对name进行了初始化
System.out.println(p1.name);//tom
}
}
class Person{
// 属性
String name;
int age;
// 构造器 默认的构造器是这样,不用写
public Person(){
System.out.println("这是构造器");
}
// 有参数的构造器
public Person(String n){
name = n;
}
// 方法
public void eat(){
System.out.println("人吃饭");
}
}
构造器与方法是不同的,需要先用构造器创建对象,再去调方法。
public class PersonTest {
public static void main(String[] args) {
Person p=new Person(23,"tom");
System.out.println(p.age);
System.out.println(p.name);
}
}
class Person{
int age;
String name;
public Person(String n){
age =18;
name =n;
}
}
TriAngle.java
public class TriAngle {
private int base;
private int height;
// 构造器
// 一般习惯性会提供一个空参构造器
public TriAngle(){
}
public TriAngle(int b,int h){
base =b;
height=h;
}
public void setBase(int b){
if (b>0){
base =b;
}else {
System.out.println("参数非法");
}
}
public int getBase(){
return base;
}
public void setHeight(int h){
if (h>0){
height=h;
} else {
System.out.println("参数非法");
}
}
public int getHeight(){
return height;
}
public int triangleArea(){
return (base*height)/2;
}
}
TriAngleTest.java
public class TriAngleTest {
public static void main(String[] args) {
TriAngle tra = new TriAngle(12,20);
System.out.println(tra.triangleArea());
tra.setBase(15);
tra.setHeight(20);
System.out.println(tra.triangleArea());
}
}
- JavaBean (拓展)
- UML类图(拓展)
关键字:this
public class TriAngle {
private int base;
private int height;
// 构造器
// 一般习惯性会提供一个空参构造器
public TriAngle(){
}
public TriAngle(int base){
this.base=base ;
System.out.println("假装有40行代码");
}
public TriAngle(int base,int height){
// 假装需要TriAngle(int base)中的40行代码,可以使用this()调用
this(base);
// 变量名需要望文生义,所以形参如果不使用this,不能区分谁是类的属性,谁是参数
this.height=height;
}
public void setBase(int base){
if (base>0){
this.base =base;
}else {
System.out.println("参数非法");
}
}
public int getBase(){
return base;
}
public void setHeight(int height){
if (height>0){
this.height=height;
} else {
System.out.println("参数非法");
}
}
public int getHeight(){
return height;
}
public int triangleArea(){
return (base*height)/2;
}
}
给私有属性快速生成get\set方法的技巧:
光标放在私有属性上,ctrl+enter呼出generate选项,选择Getter and Setter:
选择Constructor是自动生成构造器,可以选择是否带参数。
关键字package、import
- package
- MVC设计模式(拓展)
- import