六 面向对象基础
- 1.类与对象
- 1.1属性
- 1.2创建对象
- 1.3访问属性
- 1.4内存分配机制
- 2.方法
- 2.1方法调用
- 2.2传参机制
- 3.递归
- 4.方法重载
- 5.可变参数
- 6.作用域
- 7.构造方法/构造器
- 7.1对象创建流程
- 8.this关键字
1.类与对象
类:数据类型(包含属性和行为)
对象:具体的实例
class car{//car是类名
String name;//属性(成员变量)
double price;
}
1.1属性
1.定义
访问修饰符 属性类型 属性名
访问修饰符有四种:
public,proctected,默认,private
2.属性的定义类型:数据类型和引用类型
3.属性不赋值有默认值
1.2创建对象
//1.先声明后创建
Cat cat;//声明
cat = new Cat();//创建
//2.声明并创建
Cat cat = new Cat();
1.3访问属性
对象名.属性名
cat.name;
cat.age;
1.4内存分配机制
1.栈:存放基本数据类型(局部变量)
2.堆:存放对象
3.方法区:常量池(字符串),类加载信息
Person p = new Person();
p.name = "Tom";
p.age = 18;
/*
1.先加载Person类信息(只会加载一次)
2.在堆中分配空间,进行默认初始化
3.把地址赋给p,p指向对象
4.进行指定初始化(p.name = "Tom";p.age = 18;)
*/
2.方法
//1.方法写好后不调用,不会输出
//2.创建对象,调用方法
Person p = new Person();
p.speak();//调用方法
p.cal(70);//调用cal方法,计算1到70的和
int returnRes = p.getSum(19,50);
//把方法getSum的返回值赋给returnRes
class Person{
String name;
int age;
/*
1.public方法是公开的
2.void没有返回值
3.speak方法名
4.{}方法体
*/
public void speak(){
System.out.println("Hello!");
}
public void cal(int n){
//计算1到n的和
int sum = 0;
for(int i = 1;i <= n;i++){
sum += i;
}
}
public int getSum(int num1,int num2){
int res = num1 + num2;
return res;
}
}
1.一个方法最多有一个返回值
2.多个返回值用数组接收
A a = new A();
int[] res = a.getRes(10,69);
class A{
public int[] getRes(int num1,int num2){
//返回类型是int型的数组
int[][] a = new int[2];
a[0] = num1 + num2;
a[1] = num1 - num2;
return a;//返回数组a
}
}
public void f1{
return ;
//可以只写return ;
}
3.方法不可以嵌套定义
2.1方法调用
1.同一个类中的方法可以直接调用
2.跨类要创建对象后调用
A a = new A();
a.ok();
a.hi();
class A{
public void print(){
System.out.println("Hello!");
}
public void ok(){//同类调用
print();//直接调用
}
public void hi(){//跨类调用
B b = new B();//①创建对象
b.sayHi();//②调用
}
}
class B(){
public void sayHi(){
System.out.println("Hi!");
}
}
import java.util.*;
import java.util.Scanner;
/*
创建一个类AA
写一个方法判断一个数odd是奇数还是偶数返回boolean
*/
public class Main {
public static void main(String[] args) {
AA aa = new AA();
if(aa.isOdd(13)){
System.out.println("是奇数");
}else{
System.out.println("是偶数");
}
}
}
class AA{
public boolean isOdd(int num){
/* if(num % 2 == 0){
return false;
}else{
return true;
}
*/
return num % 2 != 0;
}
}
2.2传参机制
1.数据类型是值传递,不可以通过形参影响实参
2.引用类型是地址传递,可以通过形参影响实参
B b = new B();
Person p = new Person();
p.name = "Jack";
p.age = 30;
b.test(p);
//test方法里的p指向null
System.out.println("main中的p.age = " + p.age);
//main方法里的p没有滞空
//p.age = 10
class Person(){
String name;
int age;
}
class A{
public void test(Person p){
p = null;
}
}
import java.util.*;
/*
编写一个方法copyPerson
可以复制一个Person对象
返回复制的对象
新对象和原来的对象是两个对象
*/
public class t3克隆对象 {
public static void main(String[] args) {
Person p = new Person();
p.name = "Tom";
p.age = 40;
Tools tools = new Tools();
Person p1 = tools.copyPerson(p);
System.out.println("p:" + p.name + " " + p.age);
System.out.println("p1:" + p1.name + " " + p1.age);
}
}
class Person{
String name;
int age;
}
class Tools{
public Person copyPerson(Person p){
Person p1 = new Person();
p1.name = p.name;
p1.age = p.age;
return p1;
}
}
3.递归
4.方法重载
同一个类中可以有多个同名方法,但形参列表不同
T t = new T();
t.calculate(2,3);
t.calculate(2,4.3);
t.calculate(2,6,8);
class T{
public int calculate(int n1,int n2){
return n1 + n2;
}
public double calculate(int n1,double n2){
return n1 + n2;
}
public int calculate(int n1,int n2,int n3){
return n1 + n2 + n3;
}
}
方法名:必须相同
参数列表:必须不同(参数类型,个数,顺序,至少一样不同,参数名无要求)
返回类型:无要求
5.可变参数
多个同名,同功能,但参数不同的方法,封装成一个方法
访问修饰符 返回类型 方法名(数据类型… 形参名){}
1.可变参数的实参可以是数组
2.可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
3.形参列表里只能有一个可变参数
T t = new T();
t.sum(2,6,10);//18
t.sum(100,28);//128
t.sum();//接收0个参数
int[] arr = {1,3,8,10};
t.sum(arr);//1
class T{
/*
1.int...表示接受的是可变参数,类型int接收0-多个
2.可变参数可以当做数组来使用,即nums[]
*/
public int sum(int... nums){
int res = 0;
for(int i; i < nums.length;i++){
res += nums[i];
}
return res;
}
public void t(String c,int...nums){//2
/*
×××
public void t(int...nums,int n){
}
public void t(String... c,int...nums){//3
}
*/
}
}
6.作用域
Java中主要的变量:属性(成员变量),局部变量
class T{
String color;
//color是全局变量
public void cat(){
String name = "咪咪";
int age = 10;
//name,age是局部变量
//name,age的作用域在cat方法中
color = "白色";
}
public void dog(){
color = "黑色";
}
}
全局变量可以不赋值,直接使用有默认值
局部变量必须要赋值后使用,没有默认值
1.属性和局部变量可以重名,就近访问
2.同一作用域中,变量不可以同名
3.全局变量(属性)可以被本类或其它类调用
4.属性可以加修饰符,局部变量不可以
T t1 = new T();
t1.t();//输出Jary,就近
Person p = new Person();
p.test1();//Tom
p.test2(t1)//把t1传入,Tom
class Person{
public void test1(){
T t2 = new T();//跨类调用,创建对象
t2.name;
}
public void test2(T t3){
t3.name;
}
}
class T{
public String name = "Tom";//4
public void t(){
String name = "Jary";
System.out.println(name);
}
public void tt(){
System.out.println(name);
}
}
7.构造方法/构造器
修饰符 方法名(形参列表){方法体;}
完成对对象的初始化,是系统调用
1.构造器没有返回值
2.方法名和类名必须一样
3.一个类可以定义多个不同的构造器,即构造器重载
4.系统会自动生成默认构造器:方法名(){}
5.一但定义了自己的构造器,默认构造器会被
覆盖,不能使用默认除非显示定义一下Cat(){}
Person p1 = new Person();
p1.Person("Jack",20);
p1.Person("Tom");
Dog dog = new Dog();
//使用的是默认无参构造器
class Cat{
/*
默认构造器
Cat(){
}
*/
public Cat(int age){//自己定义的构造器
}
Cat(){//显示定义
}
}
class Person{
String name;
int age;
//第一个构造器
public Person(String pName,int pAge){
//构造器完成对对象的初始化
name = pName;
age = pAge;
}
//第二个构造器
public Person(String pName){
name = pName;
}
}
javap反编译:把.class文件编译成.java文件
javap 类名
7.1对象创建流程
class Person{
int age = 60;
String name;
public Person(String n,int a){
name = n;
age = a;
}
}
Person p = new Person("张三",20);
/*
1.在方法区加载Person类信息(Person.class),
只会加载一次
2.在堆中分配空间(地址)
3.给对象初始化
3.1默认初始化age = 0,name = null
3.2显示初始化age = 60,name = null
3.3构造器初始化age = 20,name = "张三"
4.把对象在堆中的地址,返回给p
*/
8.this关键字
哪个对象调用,this就代表哪个对象
Dog dog1 = new Dog("大黄",5);
Dog dog2 = new Dog("大白",3);
class Dog{
String name;
int age;
public Dog(String name,int age){
this.name = name;//当前对象的属性name
this.age = age;//当前对象的属性age
//this.当前对象的属性
}
}
1.访问成员方法:this.方法名(形参列表);
2.访问构造器:this(实参);必须放第一条语句
只能在构造器中访问构造器
3.this只能在类定义的方法中使用
class T{
public T(){
//2.访问构造器
this(18);//必须在第一条语句
System.out.println("T()构造器");
}
public T(int age){
System.out.println("T(int age)构造器");
}
public void f1(){
}
public void f2(){
//1.访问成员方法
f1();//第一种直接调用
this.f1();//第二种this.调用
}
}
import java.util.*;
/*
定义一个Person类里面有name,age属性
compareTo比较判断是否和另一个人一样
一样返回turn,否则false
*/
public class t12this {
public static void main(String[] args) {
Person1 p1 = new Person1("张三",28);
Person1 p2 = new Person1("张三",28);
Person1 p3 = new Person1("老四",8);
System.out.println("结果是:" + p1.compareTo(p2));
System.out.println("结果是:" + p1.compareTo(p3));
}
}
class Person1{
String name;
int age;
public Person1(String name,int age){
this.name = name;
this.age = age;
}
public boolean compareTo(Person1 p){
// if(this.name.equals(p.name) && this.age == p.age){
// return true;
// }else{
// return false;
// }
return this.name.equals(p.name) && this.age == p.age;
}
}