内部类
内部类
一个类中定义另一个类
外嵌类
包含内部类的类
内部类与外嵌类之间的关系
1)外嵌类的成员变量在内嵌类中仍然有效,内部类的方法可以调用外嵌类的方法
2)内部类不可声明类变量和类方法,外嵌类可用内部类声明对象作为自己成员
3) 内部类仅供它的外嵌类使用,其他类不可使用内部类声明对象
示列
package com.zpark.test;
public class RedCowForm {
static String forName;
RedCow cow;//内部类声明对象
RedCowForm(String s){
cow= new RedCow(150,112,5000);
forName=s;
}
public void showMessage(){
cow.speak();
}
class RedCow{
//内部类声明
String cowName="红牛";
int height,weight,price;
RedCow(int h,int w,int p){
height=h;
weight=w;
price=p;
}
void speak(){
System.out.println(cowName+"身高;"+height+";体重:"+weight+"生活在"+forName);
}
}
}
类里面包含一个类
并且还将这个声明的一个对象作为自己的属性
main方法
package com.zpark.test;
public class Example7_1 {
public static void main(String[] args) {
RedCowForm red = new RedCowForm("红牛农场");
red.showMessage();
red.cow.speak();
}
}
注意一下这个调用方式
如果内部类被修饰为static ,那么其他的类可以使用它来创建对象,但static内部类不能操作外嵌类的实例成员变量
内部类的字节码名字格式:外嵌类名$内部类名
注:非内部类不可以是static
匿名类
1)和子类有关的匿名类
2)和接口有关的匿名类
和子类有关的匿名类
创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明后的类体,称作匿名类
使用子类(匿名类创建对象)
匿名类类体
}
匿名类的特点
1)匿名类可以继承或重写父类的方法
2)匿名类是内部类,因为使用匿名类的时候,不然使用直接使用匿名类创建对象
3) 匿名类可以访外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法
4)由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接使用父类的构造方法
示例`
`void f(A a){
}
该方法的参数类型是A类,但用户希望传递的是A类的子类对象,但没有符合要求的子类提供,这是我们就可以考虑匿名类
创建一个抽象类
package com.zpark.test;
abstract class OutputAlphabet {
public abstract void output();
}
抽象类的实现类
package com.zpark.test;
public class OutputEnglish extends OutputAlphabet{
@Override
public void output() {
//输出英文字母的子类
for(char c='a';c<='a';c++){
System.out.println(c);
}
}
}
package com.zpark.test;
public class ShowBoard {
void showMessage(OutputAlphabet show){
//注意接受的参数的类型
show.output();
}
}
main
public class Example7_2 {
public static void main(String[] args) {
ShowBoard showBoard = new ShowBoard();
showBoard.showMessage(new OutputEnglish());
//向参数传递OutputAlphabet的子类
//outputAlphabet的对象
showBoard.showMessage(new OutputAlphabet() {
@Override
public void output() {
for(char c='a';c<='w';c++){
System.out.println(c);
}
}
});//调用该方法结束
}
}
和接口有关的匿名类
java允许直接使用接口名和一个类体直接创建一个匿名对象,此类体是实现接口的类去掉类声明后的类体,称作内部类
new Comparable(){
//实现接口的匿名类类体
}
如果某个方法的参数是接口类型,那么可以使用接口接口名和类体组合创建一个匿名对象传递给该方法的参数,类体必须重写接口中的所有方法
示例
创建一个接口
package com.zpark.test;
public interface SpeakHello {
void speak();
}
某个类的方法需要一个接口类型的对象
package com.zpark.test;
public class HelloMachine {
public void turnOn(SpeakHello speakHello){
speakHello.speak();
}
}
main
package com.zpark.test;
public class Example7_3 {
public static void main(String[] args) {
HelloMachine helloMachine = new HelloMachine();
helloMachine.turnOn(new SpeakHello() {
//和接口Speakhello有关的匿名类
@Override
public void speak() {
System.out.println("hello,you are welcome");
}
});
}
}
-------------------------------end------------------------------------------------------
实例变量与类变量的区别
1)类变量是属于类的,该类变量在内存中占有相同的一块内存,修改它的值也会影响其他对象的这个类变量的,也就是所有对象共享类变量;实例变量是属于对象的,一个使用new运算符创建不同的对象,分配给这些对象的实例变量是不同的,修改有一个对象的实例变量不会影响其他的对象的实例变量
2)new 出多个对象是,这些实例变量会被分配不同的内存空间,但类变量会在类初始化的时候就分配内存空间,而且只为类变量分配一次内存空间
3) 类变量可以通过类名和对象访问,实例变量要通过对象访问
实例方法与类方法的区别
1)实例方法需要对象来调用是,类方法可以使用对象或者类名来调用
2)类方法不可以操作实例变量,只能操作静态变量和静态方法
实例方法则没有限制
重写与重载
重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写。
原文链接:https://thinkwon.blog.csdn.net/article/details/104390612