面向对象-基础篇
前言:[*]引出类与对象(oop) -- 为什么需要类与对象(oop)
[*]例:我有两只小狗,有姓名,年龄,性别,怎么完成该操作?
//用变量
String DogName = "小白";
int DogAge = 6;
char DogSex= '公'
String DogName = "小新";
int DogAge = 6;
char DogSex= '公'
//用数组
String[] Dog = {"小白","6","公"}; //数字类型不明确
String[] Dog = {"小新","6","公"}; //数字类型不明确
[*]上面案例中完成了小狗的属性创建,那么现在我想给小狗添加一个爱好怎么办?是不是特别麻烦,如果是100只小狗呢?
类与对象是什么:
[*]看前言已经知道,用变量和数组创建一个猫是多么的麻烦,增加一个属性就需要重复大量代码
[*]类:如猫类 -> 把所有猫的属性和行为提取到该猫类中形成一个类
[*]猫类:是自定义的数据类型,如int就是java提供的数据类型
[*]对象:如猫类 -> 提供猫类去创建出来的就是对象,猫对象
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcxOTEwNDkwNjU2OS0xMzE0OTc5NDgyLnBuZw==
快速入门:
[*]看下面代码就可知道和原本的变量和数组好处在哪,属性类型明确,添加属性值方便,开发效率高
public static void main(String[] args) {
Cat cat1 = new Cat();//创建第一个猫对象
cat1.name = "小白";//给属性赋值
cat1.age = 10;
System.out.println(cat1.name +" "+ cat1.age);//输出属性值
Cat cat2 = new Cat();//创建第二个猫对象
cat2.name = "小新";//给属性赋值
cat2.age = 20;
System.out.println(cat2.name +" "+ cat2.age);
}
}
class Cat{//定义一个猫类
String name;//属性
int age;
}
[*]类属性的不同叫法和细节:
Class Cat{
String name; // 可以叫 1.属性 2.成员变量 3.字段
int[] age;// 可以放所有基本数据类型和引用类型
doeble money;
}
pring(car.name+" "+car.age...)//直接输出属性,会输出属性默认值
//int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,
//boolean false,String null
[*]对象内存布图:
[*]https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcxOTExNTAwOTg1OS00NzEyMzYyODgucG5n
类和对象的内存分配机制:
[*]java内存结构分析:
[*]栈:一般存放基本数据类型(局部变量)
[*]堆:一般存放对象或数组
[*]方法区:一般存放常量池和类加载信息
[*]java创建对象流程简单分析:
[*]创建对象然后在方法区加载类信息 -- (只是加载一次,不会创建一个对象加载一次)
[*]在堆中创建空间,进行默认初始化
[*]把栈地址指向对象
[*]进行初始化如:cat,pag = 10; cat.name = "小白"
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyMDExMjM0NzU0Mi0xNjkzNDM1NDEucG5n
成员方法:
[*]什么是成员方法?就是在类在写一个方法(方法是基础里的知识),和写一个属性是一样的
[*]为什么需要成员方法?:
[*]循环遍历一个数组 是否需要写代码遍历循环,
[*]在遍历一个数组呢,复制粘贴代码在循环一次?那我要改动遍历代码,所有的复制粘贴代码都要改?
[*]解决问题:所以只需要通过调用成员方法,就可以减少代码的复用
[*]快速入门:
public static void main(String[] args) {
Cat cat = new Cat();
cat.show();//调用方法
}
}
class Cat{
String name = "小白";
/*
public 公共的 -- 作用域(当然还有其它的)
void -- 表示方法没有返回值
int -- 表示方法返回值,基本数据类型,引用类型都可以
return -- 表示把值返回
show-- 方法名
() -- 形参列表,表示可以接收形参
{} -- 方法体
*/
public void show(){
//方法体
System.out.println("我叫"+name);
}
<br>//有参返回
public int show2(int i, int n ){
return i+n;
}
}
[*] 方法调用机制:
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyMDE1MzYyOTUwOC0xNzk0MjgxNTU2LnBuZw==
[*]方法的定义:
访问修饰符 返回数据类型 方法名(形参列表..) {//方法体
语句;
return 返回值; //如果是viod就需要该存在了}
[*]成员方法的下细节:
[*]一个方法最多一个返回值(但是可以有多个返回结果,返回数组形式)
[*]可以返回任意类型,基本数据类引用类型(数组,对象)
[*]如果方法是void,不需要写return,或者只写return(不能用返回值)
[*]返回值类型return必须和返回值统一或者兼容,如:需要返回值是double,return可以返回int,反过来就不可以需要数据类型可以转换
[*]遵循驼峰命名法
class Dog{
//1.返回多个结果
public int[] king(){
int[] sum = new int;
sum = 1;
sum = 2;
return sum; //返回多个结果
}
//2.void可以写return,但不能有返回值
public void king2(){
pring("加油");
return;
}
//3.可以返回兼容的类型
public double king3(){
inti = 99;
return i ;
}
}
[*]成员方法 - 形参列表细节:
[*]一个方法可以有0个参数,也可以有多个参数有逗号隔开
[*]参数类型可以是任意类型,基本数据类型或引用类型
[*]调用参数方法时,传入的参数一定是相同的类型或兼容的类型
[*]方法定义时的参数叫形参(形式参数),调用方法时传入的叫实参,实参和形参必须统一或兼容
//一个方法可以有0个参数,也可以有多个参数有逗号隔开
public int show(int num1, int num2){
return num1+num2;
}
//参数类型可以是任意类型,基本数据类型或引用类型
public int[][] show2(int[][] map){
int[][] nums = new int;
return nums;
}
[*]成员方法 - 方法体细节:
[*]方法体中不能嵌套方法
[*]成员方法 - 方法调用细节:
[*]同类中可以直接调用同类中的其它方法
[*]在方法中可以通过对象调用其它类中的方法 - 这里注意因为跨类调用还需要考虑访问修饰符
class A{
public void print(){
System.out.println("我在同类中的其它方法调用了");
}
//同类中可以直接调用其它方法
public void sayOK(){
print();
System.out.println("我调用了print()方法");
}
//在方法中可以,通过对象调用其它类方法
public void m1(){
System.out.println("A的m1被调用");
new B().hi();
System.out.println("A的m1现在执行 ");
}
}
class B{
public void hi(){
System.out.println("我是B类的hi()方法");
}
}
[*] 成员方法 - 基本数据类型传递机制
[*]基本数据类型传递的是值拷贝,形成不会改变实参
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyMTEyMjAwODA0Mi0xODMyNTg5NDQucG5n
[*] 成员方法 - 引用类型传递机制
[*]引用类型传递的是地址 - 会对引用类型改变
[*]如果在方法中改变了传递过去的地址,改变了地址或指空,那么对引用类型不会进行影响
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyMzE2MDIwMjg4MC01ODc2ODMyNDMucG5n
方法的重载:
[*]什么是重载?-> 同一个类中,多个方法名称一样的方法存在,但是形成列表不一致
[*]重载的好处 -> 如我的方法是显示加法后的结果,那可以是int加int,doblue加int,那么可以通过同一方法名来实现,只需要传递不同的参数
class AA{
public void show(int i ,int n){
System.out.println(i+n);
}
public void show(int i ,double n){
System.out.println(i+n);
}
public void show(double i ,double n){
System.out.println(i+n);
}
public void show(double i, int n){
System.out.println(i+n);
}
}
[*]重载细节:
[*]方法名必须相同
[*]形成列表不能一致
[*]可以是任意返回类型(如:可以返回int double void Cat 数组类型 等)
//返回形成列表不能一致,返回类型不同也不行
public void show(double i ,double n){
System.out.println(i+n);
}
public double show(double i ,double n){
System.out.println(i+n);
} 可变参数:
[*]什么是可变参数?就是可以传递零个或多个数
[*]使用可变参数,可以当数组使用
[*]语法:int... sum -- 就是int类型的可变参数
public int sum(int... nums){
int res = 0;
for (int i = 0; i < nums.length; i++) {
res += nums;
}
return res;
}
[*]可变参数 - 细节:
[*]可变参数实参可以是0个或多个
[*]可变参数的实参可以是数组
[*]可变参数本质就是数组
[*]可以参数可以和普通类型参数一起放在形成列表中,可变参数必须放在普通参数后面
[*]一个形成列表,只能出现一个可变参数
public class Test { public static void main(String[] args) { AA aa = new AA(); //可变参数的实参可以是数组 int[] num = {1,2,3}; int sum = aa.sum(num); }}class AA{ public int sum(int... nums){
int res = 0;
for (int i = 0; i < nums.length; i++) {
res += nums;
}
return res;
}
//可以参数可以和普通类型参数一起放在形成列表中,可变参数必须要在普通类型参数后面 public void sum(String name,int... nums){ };
//一个形成列表只能出现一个可变参数 //public void sum(double... num,int... nums){};//错误}作用域:
[*]什么是作用域?就是属性在该类中的使用范围
[*]作用域一般访问:全局变量和局部变量
[*]全局变量:在该类中都可以使用
[*]局部变量:只能在自己的一亩三分地使用,在自己的代码块中使用
//快速入门
class AA{
//该属性在AA类中都可以访问
String name = "king";//成员变量/属性/全局变量
public void show(){ //成员方法
//该属性只能在show()方法中使用
char sex = '男'; //局部变量
}
}
[*]作用域细节:
[*]全局变量(属性)有默认值;局部变量没有默认值(定义时必须赋值)
[*]全局变量(属性)和局部变量名字可以重复,访问时就近原则,靠我近访问谁
[*]全局变量(属性)可以使用访问修饰符,局部变量不可以
[*]全局变量(属性)伴随着对象的销毁而销毁,局部变量是代码块的销毁而销毁
[*]通俗易懂版:new一个对象,该对象不销毁全局变量还在,局部变量一般中方法中,如方法结束局部变量就销毁
class AA{
//1.属性默认值:String是null
String name;
//2.属性和局部变量名字可以一致,就近原则访问
int age;
//3.属性可以使用访问修饰符
public char sex;
public void show(){
//1.局部变量:没有默认值,不写就错
char sex = '男';
//2.属性和局部变量名字可以一致,就近原则访问
int age = 18;
}
} 构造器:
[*] 什么是构造器?完成对新对象的初始化
[*]理解:调用构造器时,对象已存在内存中,调用构造器去完成对象属性的的初始化
[*]在理解:等于AA类中有 String name; 我的操作等于 String name = "小白";
[*]语法:【修饰符】类名 (形参列表) {代码块}
class AA{
String name;
int age;
public AA(String name,int age){
System.out.println("name+age");
name = name;
age = age;
}
}
[*]构造器 - 细节:
[*]可以构造器的重载
[*]控制器没有返回值
[*]控制器名和类名相同
[*]构造器完成对象的初始化,不是创建对象
[*]类中没有定义构造器,系统默认是给一个默认的无参构造器
[*]定义了自定义的构造器后,默认的构造器就会被覆盖,需要重新定义才能使用
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyNjEwNDczMTQ5OS0zNDkyNTQyMTQucG5n
对象创建的流程+构造器版本:
[*]类加载
[*]在堆在分配空间 == 空对象
[*]对象初始化 - 属性先赋值(默认值先赋值,在到定义值,在到构造器)
[*]栈中接收堆中地址
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyNjExMzcxNjY5My0xOTQ1NzUxMTY5LnBuZw==
this关键字:
[*]什么是this?我直接调用我自己
[*]为什么要使用this?如:构造器中形参为 name 类属性 name 我要name = name怎么办?是不是太含糊不清,谁是谁的name
[*]案例说明什么是,我直接调用我自己:
public class Test {
public static void main(String[] args) {
AA aa = new AA("小白",20);
//1.调用该方法name = null,age = 0
aa.show();
}
}
class AA{
String name;
int age;
public AA(String name, int age) {
//2.因为:这里把name当成了局部变量
//自己 给 自己 赋值肯定是错误的
name = name;
age = age;
//3.this.name表示当前对象的name属性
//当前对象是谁?AA aa = new AA("小白",20);
//所以说是:我自己调用我自己
this.name = name;
this.age = age;
}
public void show(){
System.out.println(name+" "+age);
}
}
[*]深入了解,我自己调用我自己:
[*]每个对象都会有一个hashcode,Java可以通过这个hashcode来识别一个对象
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pbWcyMDIyLmNuYmxvZ3MuY29tL2Jsb2cvMjkyNTcyMy8yMDIyMDcvMjkyNTcyMy0yMDIyMDcyNjE1NDcwODUzNi0xOTE5ODc2ODU1LnBuZw==
[*]this细节:
[*]this关键字可以访问,本类属性,方法,构造器
[*]访问方法语法:this.方法名(参数列表)
[*]访问构造器语法:this(参数列表) - 必须写在构造器中使用,必须在构造器中第一条中,不能递归调用(就是我调用你,你调用我)
[*]this关键字可以区分属性和局部变量
[*]this关键字只能在类定义的内部使用,去类外部使用谁知道this是什么
class AA{
String name;
int age;
public AA(String name, int age) {
//this关键字访问本类构造器
this("小白");
//this关键字访问本类属性
this.name = name;
this.age = age;
}
public AA(String name) {
String name = "oop";
//this关键字可以区分属性和局部变量
this.name = name;
this.age = age;
}
public void t1(){
//this关键字可以访问本类方法
this.t2();
System.out.println("我是t1");
}
public void t2(){
System.out.println("我是t2");
}
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]