java类和对象一般的类只能是public或者default的,若是public的,类名必须和文件名一样。一般在一个文件只写一个类,故这个类一般是加上public。
内部类还可以是private和protected,一般私有化(private),因为只有当前这个类才需要。这样只有它的外部类可以直接访问。所以里面的数据也无所谓是public还是private或者default的。
public class out {private int d = 10;public int add() { // 外部类不能直接访问内部类的数据,除非new出内部类对象,如下 // out.in abc = new out().new in();a = 3; // falseb = 5; // false} // 内部类private class in {private int a = 100;int b;public int c;public void add() {
system.out.println(d); // true, 内部类却可以直接访问外部类的数据}
}public static void main(string[] args) {
out bb = new out();
out.in abc = new out().new in();
bb.d = 20; // 本类可以直接访问private,一般不这样,而是写个set函数,搭配get函数system.out.println(aa.a); // 100system.out.println(bb.d); // 被修改为20}
}
匿名对象
new abc().run(); // 调用一次后这个对象就销毁new abc().run(); // 这是另外一个abc对象了
关于private
private变量:封装数据,只给用户看方法。例如private string name不能随修改,但是提供setname()、getname()方法可调用,实现数据的封装,更安全。
private方法:不用用户调用的函数,完成一些内部实现的细节,就可以定义成private。例如选择排序算法写成一个方法,里面有交换两个数据的过程,封装成函数。这个函数不需给用户操作(用户只需用一个sort()就行),这个swap()就定义成private的。
单例设计模式可以保证一个类在内存中的对象唯一性,需对过个程序使用同一配置信息对象时,就需要保证对象的唯一性,这时就需要单例。
工具类中,未用到(访问)对象成员数据,则可不用创建对象。为了防止创建对象,可以将构造函数定义为private。
如何保证对象的唯一性?不允许其他程序用new创建该类对象,构造函数设为private
在该类创建一个唯一的类实例
对外提供一个方法使其他程序可以获取到这个唯一对象
单例设计步骤私有化(private)该类的构造函数
通过new在本类汇总穿件一个本类对象
定义一个puiblic方法,将2中创建的对象返回
饿汉模式// 饿汉式--不管用不用得到,先new出一个再说public class singledemo {// private不能将这个实例暴露出去,只能通过getinstance()获取,另为何是static?private static singledemo s = new singledemo();private singledemo() {}// 供外界调用来获取这个对象public static singledemo getinstance() {return s;
} // 只有本类中可以new对象并调用addpublic void add() {
system.out.println("danli");
}public static void main(string[] args) { // 本类可以newsingledemo a = new singledemo();
a.add();
}
}public class test {public static void main(string[] args) { // fasle, 其他类中若用到这个单例,不能newsingledemo aa = new singledemo(); // true singledemo aa = singledemo.getinstance();
}
}
懒汉模式// 另外一种单例设计模式--懒汉模式--用到了才new,延时加载public class singledemo {// 先设为空private static singledemo s;private singledemo() {}// 供外界调用来获取这个对象public static singledemo getinstance() { if (s == null)
s = new singledemo();return s;
}
q:为何成员变量是static,方法也是static?
a:因为在其他类中,不允许new出新对象,故不能调用getinstance(),如果我们设成静态方法,就可以通过single.getinstance()来获取而无需new对象,又静态方法里的数据也必须是static的。故这个singledemo对象也必须是static的。
q:饿汉模式和懒汉模式的区别?
a:懒汉模式是延时加载的,用到了才new;在多线程时不能保证对象的唯一性,是线程不安全的。饿汉模式是随着类的加载,就new出这个对象,不管用不用得上,是线程安全的。
继承java一般是单继承,不能直接多继承 --> 因为多个父类可能有相同的成员,调用会导致二义性。
但是可以多层继承,如 a --> b -->c--> d,可以表示a继承自b,而b继承自c,以此类推。
本类成员和局部变量之间用this区分
子类、父类的成员同名时用super区分
派生类也不能访问基类的private成员,但是确实是继承过来了,只是不能访问而已,可以调用父类的set、get函数来操作子类的private成员,对父类没影响。
若成员是protected等权限更高的,则不用set、get就可直接访问该成员。
父类与子类的该成员是相互独立的,子类改变它自己的成员,父类保持原样。
package chap1;public class fu { // 父类的成员是私有的,子类继承过去了也不能直接访问
private int age;private string name;public fu(int age, string name) {this.age = age;this.name = name;
}public int getage() {return age;
}public void setage(int age) {this.age = age;
}public string getname() {return name;
}public void setname(string name) {this.name = name;
}
}class zi extends fu { // 特有的job,父不能访问private string job;zi(int age, string name, string job) {super(age, name);this.job = job;
}public string getjob() {return job;
} public static void main(string[] args) {
zi aa = new zi(23, "zi","study");
fu bb = new fu(55, "fu"); // 改变子类不会影响父类aa.setage(24);
aa.setname("zi"); // zi 24 study // fu 55system.out.println(aa.getname()+" "+aa.getage() + " " + aa.getjob());
system.out.println(bb.getname()+" "+bb.getage());
}
}
子类隐式执行super(),new一个子对象时,先调用父类的构造函数,再执行子类的构造函数。
默认的构造函数是无参的,有参数的构造函数会覆盖无参的。这时候需要显式使用super(args),且必须放在第一行,若不显式写super,则执行默认的super(),即无参的父类构造函数。
class fu { // 构造函数
fu() {
system.out.println("father");
} // 带参的构造函数
public fu(int age, string name) {this.age = age;this.name = name;
}
}class zi extends fu {
zi() {private string job;// super() 会打印“father”// 无参数时是默认构造器,这句super()可以不写。父类的构造函数默认执行,先执行//
}
zi(int age, string name, string job) {// 若不写,会默认调用无参的super()打印fathersuper(age, name);this.job = job;
}
}
类是public,构造函数也是public的。他们的修饰符是对应的。
一个对象的实例化过程person p = new person();
jvm读取person.class文件,加载进内存;若有父类,会先加载父类。
在堆内存中开辟空间,分配地址。
在对象空间中,对对象的属性进行默认初始化,如int age = 0; string name = null;
显示初始化,如private int age = 9。若是子类,则会先调用父类的构造器。
(子)类的 构造函数进行特定的初始化。如下程序中age变成100。
初始化后,将地址传递给引用变量。person p <-- new person();
package test;// 先打印9// 再打印100public class demo {private int age = 9;
{
system.out.println(age);
}demo(int age) {this.age = age;
}public static void main(string[] args) {
demo aa = new demo(100);
system.out.println(aa.age);
}
}
以上就是java基础之类和对象、单例模式、继承的详细内容。