类的内部成员
一:属性(成员变量)
1:成员变量 VS 局部变量
2:如何声明
3:属性封装概念
二:方法
1:基本概念
权限修饰符 返回值类型 方法名(形参列表){
方法体
}
方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
第一个单词首字母小写,其他单词首字母大写
2:四类方法
序号 | 链接 |
---|---|
1 | 无参无返回、无参带返回值、带参无返回值、带参带返回值 |
3:返回值类型: 返回值 vs 没返回值
- 要返回值,指定返回值的类型。使用return关键字来返回指定类型的变量或常量:“return 数据”。
- 没返回值,void来表示,不需要使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思。
4:特殊方法
- 静态方法:static
声明格式:权限修饰符 static 返回值类型 方法名(形参列表){
方法体}
静态方法中,只能调用静态的方法或属性
public static void show(){
System.out.println("我是一个中国人!");
// 不能调用非静态的结构
// eat();
// name = "Tom";
// 可以调用静态的结构
System.out.println(Chinese.nation);
walk();//静态方法
}
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
public void eat(){
System.out.println("中国人吃中餐");
//调用非静态结构
this.info();
System.out.println("name :" +name);
//调用静态结构
walk();
System.out.println("nation : " + nation);
}
注意
随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
在静态的方法内,不能使用this关键字、super关键字,因为不需要实例就可以访问static方法扫描二维码关注公众号,回复: 13134739 查看本文章![]()
- 抽象方法:abstract
声明一个方法但不提供实现,该方法的实现由子类提供
声明格式:【修饰符】 abstract 返回值类型 方法名(形参列表);
注意:
- 抽象方法只有方法的声明,没方法体
- 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
- 若子类重写了父类中的所有抽象方法后,此子类方可实例化
- 若子类没重写父类中的所有抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
5:方法重载
6:方法重写
7:方法的递归
递归方法:一个方法体内调用它自身
// 例1:计算1-n之间所自然数的和
public int getSum(int n) {
// 3
if (n == 1) {
return 1;
} else {
return n + getSum(n - 1);
}
}
// 例2:计算1-n之间所自然数的乘积:n!
public int getSum1(int n) {
if (n == 1) {
return 1;
} else {
return n * getSum1(n - 1);
}
}
//例3:已知一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
//其中n是大于0的整数,求f(10)的值。
public int f(int n){
if(n == 0){
return 1;
}else if(n == 1){
return 4;
}else{
// return f(n + 2) - 2 * f(n + 1);
return 2*f(n - 1) + f(n - 2);
}
}
//例4:斐波那契数列
......
//例5:汉诺塔问题
......
//例6:快排
......
8:可变形参
举例:
public void show(int i){
}
public void show(String s){
System.out.println("show(String)");
}
public void show(String ... strs){
System.out.println("show(String ... strs)");
for(int i = 0;i < strs.length;i++){
System.out.println(strs[i]);
}
}、
调用时:
test.show("hello");
test.show("hello","world");
test.show();
test.show(new String[]{
"AA","BB","CC"});
9:方法参数传递
三:构造器(构造方法)
1:如何声明
2:代码块
静态代码块
- 内部可以输出语句
- 随着类的加载而执行,而且只执行一次
- 作用:初始化类的信息
- 静态代码块的执行要优先于非静态代码块的执行
非静态代码块
- 随着对象的创建而执行
3:执行特点和加载顺序
- 执行特点:静态代码块(只执行一次)–》构造块(每次创建对象) --》构造器(每次创建对象)
- 加载顺序:总结:由父及子,静态先行(涉及到父类、子类中静态代码块、非静态代码块、构造器的加载顺序)
四:内部类
成员内部类
1:如何声明:
【修饰符】 class 外部类{
【修饰符】 class 内部类{
}
}
2:在外部类的外面使用内部类:
- 它需要外部类的对象,才能获得内部类的对象等
示例一:
class Outer{
class Inner{
}
}
//使用
Outer.Inner inner = new Outer().new Inner();
Outer out = new Outer();
Outer.Inner inner = out.new Inner();
示例二:
class Outer{
class Inner{
}
public Inner getInner(){
return new Inner();
}
}
//使用
Outer out = new Outer();
Outer.Inner in = out.getInner();
示例三:
class Outer{
class Inner{
}
}
//继承 Inner
MyClass需要调用Inner的构造器
而调用Inner的构造器,需要外部类Outer的对象
class MyClass extends Outer.Inner{
public MyClass(Outer out){
out.super();
}
}
3:其他特点:
静态内部类
1:如何声明:
【修饰符】 class 外部类{
【修饰符】static class 内部类{
}
}
(1)需要在内部类中声明静态成员,那么这个内部类必须是static
(2)需要在外部类的静态成员中使用这个内部类,那么这个内部类也必须是static
2:如何使用:
(1)在外部类中使用:没有限制
(2)在外部类的外面
示例一:
class Outer{
static class Inner{
public void test(){
}
}
}
//如何调用test()
(1)从test()看,它不是静态的,因此需要Inner的对象
(2)Inner在Outer里面,而Inner又是static修饰
Outer.Inner in = new Outer.Inner();
in.test();
示例二:
class Outer{
static class Inner{
public static void test(){
}
}
}
//使用test()
(1)看test(),是static修饰符,说明不需要Inner对象
(2)看Inner是static修饰,也不需要外部类的对象
Outer.Inner.test();
(3)在内部类中使用外部类的成员
- 在静态内部类中,不能使用外部类的非静态成员
- 其他的成员可以直接使用,包括私有的
局部内部类
1: 如何声明:
【修饰符】 class 外部类{
【修饰符】 返回值类型 方法名(形参列表){
class 内部类名{
}
}
}
2:如何使用:
3:其他特点
(1)不能使用public,protected,private,static这些成员修饰符
(2)局部内部类也有自己的字节码文件:外部类$编号内部类.class
匿名内部类
1:如何声明
【修饰符】 class 外部类{
【修饰符】 返回值类型 方法名(形参列表){
new 父类/父接口(){
//内部类的成员
}
}
}
注意:此处,父类要注意是否有无参构造
2:如何使用
(1)使用父类的多态引用使用它对象
- 只能调用父类中声明过的方法
package com.atguigu.review;
//在main中,写一个Father的匿名内部类的对象
public class TestNiMing {
public static void main(String[] args) {
Father f = new Father("尚硅谷"){
/*@Override
public String getInfo() {
return "内部类的示例:" + getInfo();//java.lang.StackOverflowError
}*/
@Override
public String getInfo() {
return "内部类的示例:" + super.getInfo();
}
public void method(){
System.out.println("匿名内部类自己的方法");
}
};
System.out.println(f.getInfo());
// f.method();//无法访问
}
}
class Father{
private String info;
public Father(String info) {
super();
this.info = info;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
(2)本态引用调用方法
- 可以调用父类的方法,也可以调用子类自己的方法
public static void main(String[] args) {
//父类是Object,使用匿名内部类,声明一个方法void fun(),并调用
new Object(){
public void fun(){
System.out.println("匿名内部类的方法");
}
}.fun();
}
(3)作为方法的实参
package com.atguigu.review;
import java.util.Arrays;
import java.util.Comparator;
public class TestLocal3 {
public static void main(String[] args) {
Dog[] dogs = new Dog[3];
dogs[0] = new Dog(7.8);
dogs[1] = new Dog(5.8);
dogs[2] = new Dog(9.8);
Arrays.sort(dogs, new Comparator(){
@Override
public int compare(Object o1, Object o2) {
Dog d1 = (Dog) o1;
Dog d2 = (Dog) o2;
if(d1.getWeight() > d2.getWeight()){
return 1;
}else if(d1.getWeight()
return -1;
}
return 0;
}
});
}
}
class Dog{
private double weight;
public Dog(double weight) {
super();
this.weight = weight;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}