数组
package com.lv.array;
public class ArrayDemo01 {
//变量的类型 变量的名字 = 变量的值;
public static void main(String[] args) {
int[] num;//两种声明方法 首选方法
// int num2[];
int sum=0;
num=new int[10];//这里可唔可以存放10个int类型的数组
//给数组元素赋值
num[0]=1;
num[1]=2;
num[2]=3;
num[3]=4;
for (int i = 0; i <num.length; i++) {// 获取数组长度 arrays.length
sum=num[i]+sum;//求所有数的和
}
System.out.println(sum);
}
}
内存分析
存放new的对象和数组
堆 可以被所有的线程共享,不会存放别的对象引用
存放基本变量类型(会包含这个基本类型的基本数值)
Java 栈 引用对象的变量(会存放这个引用在堆里面的具体地址)
可以被所有的线程共享
方法区 包含了所有的 class和static变量
静态初始化
int [] a={1,2,3};
Man[] mas ={new Man(1,1),new Man(2,2)}
动态初始化
int[] a= new int[2];
a[0]=1;
a[1]=2;
数组默认初始化
数组是引用类型,他的元素相当于类的变量,因此数组一经分配,其中的每一个元素也被按照实例变量同样的方式被隐式初始化。
package com.lv.array;
public class ArrayDemo02 {
public static void main(String[] args) {
//静态初始化
int[] a={1,2,3,4,5};
System.out.println(a[3]);
System.out.println("========================================");
//动态初始化 包含默认初始化
int[] b=new int[10];
b[0]=2;
System.out.println(b[0]);
}
}
数组边界
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合
- 数组也是有对象的,数组元素相当于对象的成员变量
- 数组长度确定,不可变的,如果越界则会报错 ArrayIndeOutofBounds
数组的一些应用
package com.lv.array;
public class ArrayDemo03 {
public static void main(String[] args) {
int[] array= {1,2,3,4,5};
int sum=0;
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);//打印数组的元素
//计算数组的总和
sum=sum+array[i];
}
System.out.println(sum);
//找出数组中最大的数
int max=array[0];
for (int i = 0; i < array.length; i++) {
if(max>array[i]){
max=max;
}else{
max=array[i];
}
}
System.out.println(max);
}
}
package com.lv.array;
public class ArrayDemo04 {
public static void main(String[] args) {
int[] array={1,2,3,4,5};
int[] reverse=reverse(array);
prinArray(reverse);
}
//将数组元素反过来
public static int[] reverse(int[] array){
int[] result=new int[array.length] ;
for (int i = 0,j=result.length-1; i <array.length;i++,j--) {
result[j]=array[i];
}
return result;
}
//打印数组元素
public static void prinArray(int[] array){
for (int i = 0; i < array.length ;i++) {
System.out.println(array[i]);
}
}
}
二维数组
package com.lv.array;
public class ArrayDemo05 {
public static void main(String[] args) {
int[] array={1,2,3,4,5};
//=========================================
int[][] arrays= {{1,2},{2,3}};//二维数组
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays[i].length; j++) {
System.out.println(arrays[i][j]);
}
}
printArray(arrays[1]);//打印数组元素
}
//打印数组元素
public static void printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Arrays的一些运用
package com.lv.array;
import java.util.Arrays;
public class ArrayDemo06 {
public static void main(String[] args) {
int[] a={1,2,3,34,5,6,7};
Arrays.sort(a);//数组重新排序
System.out.println(Arrays.toString(a));//打印数组元素
Arrays.fill(a,2,4,0);//数组的填充
System.out.println(Arrays.toString(a));//打印数组元素
}
}
冒泡排序
冒泡排序是最为出名的排序算法之一,总共有八大排序算法
package com.lv.array;
//冒泡排序
/*
1.比较数组中两个相邻的元素,如果第一个比第二个元素大,就交换他们的位置;
2.每一次比较都会产生出一个最大,或者最小的数字;
3.下一轮则可以少一次排序;
4.依次循环直到结束;
*/
import java.util.Arrays;
public class ArrayDemo07 {
public static void main(String[] args) {
//
// int[] a={1,2,4,5,9,} ;
// int[] sort = sort(a);//调用完我们自己写的排序方法以后,返回一个排序过后的数组;
// System.out.println(Arrays.toString(a));
//
// }
// public static int[] sort(int[] a){
// int temp=0;//临时变量;
// for (int i = 0; i < a.length-1; i++) {//外层循环,判断我们的循环要走多少次;
// for (int j = 0; j < a.length-1-i; j++) {//内层循环;
// //比较两个数,如果第一个比第二个元素大,就交换他们的位置;
// if (a[j]>a[j+1]){
// temp=a[j];
// a[j]=a[j+1];
// a[j+1]=temp;
//
// }
// }
//
// }
// return a;
//
// int[] array={1,2,3,4,5,4,3,2,1};
//
// int[] sort = sort(array);
// System.out.println(Arrays.toString(array));
//
//
// }
// public static int[] sort(int[] array){
// int temp=0;
// for (int i = 0; i < array.length-1; i++) {
// for (int j = 0; j < array.length-i-1; j++) {
// if (array[j]>array[j+1]){
// temp=array[j];
// array[j]=array[j+1];
// array[j+1]=temp;
// }
//
// }
//
// }
// return array;
int[] b={3,6,34,6,7,654,78,8,2,11,1423};
int[] sort = sort(b);
System.out.println(Arrays.toString(sort));
}
public static int[] sort(int[] b){
int temp;
for (int i = 0; i < b.length-1; i++) {
for (int j = 0; j < b.length-1-i; j++) {
if (b[j]>b[j+1]){
temp=b[j];
b[j]=b[j+1];
b[j+1]=temp;
}
}
}
return b;
}
}
面向对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKJzcOS0-1613779801612)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210130202918800.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AwRKFhTk-1613779801616)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210130203037284.png)]
package com.oop.demo01;
//Demo01 类
public class Demo01 {
//main方法
public static void main(String[] args) {
/*
修饰符 返回值类型 方法名(···){
方法体;
return 返回值;
*/
}
//return 结束方法 返回一个结果!;
public String sayHello(){
return "hello world!";
}
public void print(){
return;
}
public int max(int a,int b){
return a>b?a:b;//三元运算符,如果a>b则输出a,否则输出b;
}
}
方法复习
package com.oop.demo01;
public class Demo02 {
//静态方法 使用static
public static void main(String[] args) {
Student.say();//静态方法可以使用类名.方法名调用
//=========================================
//实例化这个类 new
//对象类型 对象名=对象值
Student student = new Student();//非静态调用方法
student.say1();
System.out.println(student);
}
//非静态方法
}
package com.oop.demo01;
//学生类
public class Student {
//方法
//这里是 静态方法 没有使用 static
public static void say(){
System.out.println("学生说话了");
}
//非静态方法 没有static
public void say1(){
System.out.println("学生又说话了");
}
}
值传递 和 引用传递
值传递
package com.oop.demo01;
//值传递
public class Demo04 {
public static void main(String[] args) {
int a=1;
System.out.println(a);
Demo04.change(a);
System.out.println(a);
}
//返回值为空
public static void change(int a){
a=10;
}
}
引用传递
package com.oop.demo01;
//引用传递 传递对象,其本质还是值传递
public class Demo05 {
public static void main(String[] args) {
Perosn perosn = new Perosn();
System.out.println(perosn.name);
change(perosn);
System.out.println(perosn.name);
}
public static void change(Perosn perosn){
//perosn 是一个对象---->指向Perosn perosn=new Perosn(); 这里是具体的人,可以改变属性;
perosn.name="lv";
}
}
///定义了一个Perosn类,有一个属性:name
class Perosn{
String name ;
}
new
package com.oop.demo02;
public class Student {
//属性: 字段
String name;//默认初始null
int age;//默认0;
//方法
public void study(){
System.out.println(this.name+"学生在学习");
}
}
面向对象编程的本质是:以类的方式组织代码,以对象的形式组织(封装)数据;
package com.oop.demo02;
public class Application {
public static void main(String[] args) {
//类 抽象的,实例化
/*
new 关键之创建的的时候,除了分配空间之外
还会给创建的对象 默认初始化 以及构造器的调用
*/
Student xiaoMing = new Student();
Student xiaoLing = new Student();
Student xiaoXing = new Student();
xiaoMing.name="小明";
xiaoMing.age=15;
System.out.println(xiaoMing.name +xiaoMing.age);
}
}
创建初始化对象
new 关键之创建的的时候,除了分配空间之外还会给创建的对象 默认初始化 以及构造器的调用
类的构造器也称为构造方法,实在惊醒创建对象的时候必须调用的,并且构造器有以下两个特点:
- 必须和类名相同;
- 必须没有返回值类型,也不能写void
构造器
package com.oop.demo02;
public class Person {
//一个类即使什么都不写,他也会存在一个方法
//必须和类的名字相同
// 必须没有返回值,不能有void
String name;
//可以实例化初始值
//使用new关键字 本质是在调用构造器 2.用来初始化值
public Person() {//无参构造
}
public Person(String name){//有参构造,一旦定义了有参构造,无参构造就必须显示定义
this.name=name;
}
//==============================
//alt +insert 快捷有参和无参构造器
//
// public Person(String name) {
// this.name = name;
// }
//
// public Person() {
// }
public static void main(String[] args) {
//new关键字 实例化了一个对象
Person person = new Person("lv");
System.out.println(person.name);
}
}
/*
构造器:
1.和类名相同
2.没有返回值
作用:
1.new 本质是调用构造器
2.初始化对象的值
注意点:
1.定义了有参构造,如果想使用无参构造,必须显示定义一个无参构造
alt+insert
*/
内存分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JJNlEAld-1613779801618)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210131112710307.png)]
package com.oop.demo03;
public class Pet {
public String name;
public int age;
public void shot(){
System.out.println(this.name+"叫了一声");
}
public static void main(String[] args) {
Pet dog = new Pet();
dog.name="旺财";
dog.age=3;
Pet cat = new Pet();
cat.name="凯特";
cat.age=2;
System.out.println(dog.name);
System.out.println(dog.age);
System.out.println(cat.name);
System.out.println(cat.age);
}
}
小节 回顾
package com.oop.demo03;
public class Demo01 {
/*
1.类与对象
类是一个模板:抽象,对象是一个具体的实例
2.方法
定义 、调用
3.对应的引用
引用类型 基本类型(8)
对象是通过引用来操作的 栈--->堆
4.属性: 字段field 成员变量
默认初始化:
数字: 0 0.0
char: u0000
boolean:false
5.对象的创建和使用
---必须使用new创建对象,构造器 Person lv = new Person;
---对象的属性 lv.name;
---对象的方法 lv.sleep();
6.类
静态的属性 属性
动态的方法 方法
7. 封装、继承、多态
*/
}
封装
程序设计要追求:“高内聚,低耦合”。高内聚就是类的内部操作细节自己完成,不允许 外部干涉,低耦合 :仅暴露少量的方法给外部使用
封装(数据的隐藏)
通常应禁止直接访问一个对象中的数据的实际表现,而应通过操作接口来访问,这称为信息隐藏
属性私有,get/set
package com.oop.demo04;
import java.util.Scanner;
//类
public class Student {
//private 私有
private String name;
private int age;
private char sex;
/*
1.提高了程序的安全性,保护数据;
2.隐藏代码的实现细节;
3.统一接口;
4.系统的可维护性增加了;
*/
public void study(){
System.out.println("学生学习");
}
//get 获得这个数据
public String getName() { //alt + insert;快捷生成get/set
return name;
}
//set 为这个数据设置值
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >120||age<0){
System.out.println("你输入的年龄误");
}else{
this.age = age;
}
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
//===========================================================
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Student lv = new Student();
lv.setName("lv");
lv.study();
System.out.println(lv.getName());
System.out.println("请输入你的年龄");
lv.setAge(scanner.nextInt());
if (lv.getAge()!=0) {
System.out.println("你的年龄为" + lv.getAge() + "岁");
}
}
}
继承
继承的本质是对某一批的抽象类,从而实现对现实世界更好的建模
extends 的意思是 “拓展”.子类是父类的拓展;
JAVA中类只有继承,没有多继承;(一个爸爸可以有多个儿子,但是一个儿子只有一个爸爸)
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有 依赖、组合、聚合等。
继承关系的俩类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键之extends来表示。
子类和父类之间,从意义讲应该具有“is a“的关系。
public class Student extends Person{
}
私有的将无法被继承
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kic4Hvp1-1613779801620)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210131162718697.png)]
子类将会继承父类的全部方法
object类
super类
方法重写
在Java中都默认直接或间接继承object类 //alt+h 调出继承树
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
VS this:
代表的对象不同:
this: 本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法
this(); :本类的构造
super(); :父类的构造
package com.oop;
import com.oop.demo05.Student;
import java.util.Scanner;
public class Application {
public static void main(String[] args) {
Student student = new Student();
// System.out.println(student.age);
// student.test();
}
}
package com.oop.demo05;
public class Student extends Person {
private String a="你好1";
public Student() {
super();
//这是隐藏的代码,调用了父类的无参构造
//调用父类的构造器,必须在子类构造器的第一行
System.out.println("调用了子类的Student");
}
public void prinnt(){
System.out.println("你好3");
}
public void test(){
prinnt();
say("你好");
System.out.println(this.a);
System.out.println(super.a);
}
}
package com.oop.demo05;
public class Person {
public int age=10;
public String a="你好2";
public void say(String a){
System.out.println("你好");
}
public Person() {
System.out.println("调用了父类的Perspn");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lf0QJlfo-1613779801621)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210131170018313.png)]
重写 :需要有继承关系, 子类重写父类的方法!
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大 Public >Protected>Default>Private
- 抛出的异常: 范围可以被缩小 但不能扩大
重写 , 子类的方法和父类必须一致,方法体不同
package com.oop;
import com.oop.demo05.A;
import com.oop.demo05.B;
public class Application {
public static void main(String[] args) {
//静态方法和非静态方法有区别 static
//静态方法: 方法的调用只左边有关(定义的数据类型)
//非静态 重写 !public
B a=new B();
a.test();
//父类的引用指向子类
B b=new A();//子类重写了父类的方法
b.test();
}
}
package com.oop.demo05;
public class A extends B{
@Override//注解 有功能的注释 override 翻译:重写
public void test() {
System.out.println("A=>test");
}
// public void test(){
// System.out.println("A=>test");
// }
}
package com.oop.demo05;
public class B {
public void test(){
System.out.println("B=>test");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O4m3kYeD-1613779801622)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210131181902733.png)]
思考 为什么需要重写
1. 父类的功能,子类不一定需要,或不一定满足!
2. alt +insert
多态
动态编译: 类型:可扩展性
即同一方法可以根据发送对象不同二采用不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
package com.oop;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
public class Application {
public static void main(String[] args) {
//一个对下个的实际类型是确定发
//new Student()
//new Person()
//可以指向的引用类型就不确定了,父类的引用指向了类
//
//
//Student 能调用的方法都是自己的或者继承父类的
Student st2=new Student();
//Person 父类型,指向子类,但是不能调用子类独有的方法
//意思是子类和父类都有同一种方法
Person st1 = new Student();
Object st3=new Student();
//对象能执行哪些方法,只要看左边的的类型,和右边的关系不大
st1.eat();
st2.run();
}
}
package com.oop.demo06;
public class Student extends Person {
public void eat(){
System.out.println("eat子");
}
public void run(){
System.out.println("run子");
}
}
package com.oop.demo06;
public class Person {
public void run (){
System.out.println("run父");
}
public void eat(){
System.out.println("eat父");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LwKHFnWt-1613779801623)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210131202653785.png)]
多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向类的对象
注意: 多态是方法的多态,属性没有多态性;
多态的注意事项
- 多态是方法的多态,属性是没有多态的
- 父类和子类 ,有联系, 类型转换异常!classCastException!
- 存在的条件: 继承关系 、 方法重写 、 父类引用指向子类对象
不能重写 :
1. static 方法,属于类,不属于实例
2. final 常量,无法改变
3. private 私有,
Instanceof 类型转换 指的是引用类型的转换
package com.oop;
import com.oop.demo07.Person;
import com.oop.demo07.Student;
public class Application {
public static void main(String[] args) {
//高-------------------------低(低到高自动转换)
// Student类可直接转换为Person类型
Person student = new Student();
// student.go; 这里不能使用go方法 因为student 为Person类 这个类里面没有go()方法
//所以需要把student强制转换为Student类才能调用go()方法
Student student1 = (Student) student;// (Student)student;
student1.go();
//上面代换可以简化为下面的代码
((Student)student).go();
Student student2 = new Student();
Person person=student2;
// person.go();//将子类Student转化为父类Person,这里的go()方法不能使用了
// 可能会丢失自己本来的一些方法
}
}
package com.oop.demo07;
public class Student extends Person {
public void go(){
System.out.println("go");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFO8RYYf-1613779801624)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210131205821573.png)]
- 父类的引用指向子类的对象
- 把子类转换为父类 向上转型 自动转换 低------------>高
- 把父类转换为子类 向下转型 强制转换 高------------>低 可能会丢失原来的方法
- 方便方法的调用 减少代码的重复,让代码简介
抽象: 封装 – 继承 --多态 抽象类 接口