static关键字和继承
案例题目------------------------------
编程实现People类的封装,特征有:姓名,年龄,国籍,要求提供打印所有特征的方法
编程实现PeopleTest类,main方法中使用有参方式构造两个对象并打印
public class People {
private String name;
private int age;
private static String country;
public People ( ) {
}
public People ( String name, int age) {
setName ( name) ;
setAge ( age) ;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age) {
if ( age > 0 && age < 150 ) {
this . age = age;
} else {
System . out. println ( "年龄不合理" ) ;
}
}
public static String getCountry ( ) {
return country;
}
public static void setCountry ( String country) {
People . country = country;
}
public void show ( ) {
System . out. println ( "该学生的姓名是:" +
getName ( ) + ",年龄是:" + getAge ( ) + ",国籍是:" + getCountry ( ) ) ;
}
}
public class PeopleTest {
public static void main ( String [ ] args) {
System . out. println ( "国籍是" + People . getCountry ( ) ) ;
People p1 = new People ( "张三" , 14 ) ;
p1. show ( ) ;
People p2 = new People ( "李四" , 15 ) ;
p2. show ( ) ;
System . out. println ( "-----------------------------------------------" ) ;
p1. setCountry ( "蜀国" ) ;
System . out. println ( "第一个国籍是" + p1. getCountry ( ) ) ;
System . out. println ( "第二个国籍是" + p2. getCountry ( ) ) ;
People p3 = new People ( ) ;
System . out. println ( "第三个国籍是" + p3. getCountry ( ) ) ;
}
}
使用static关键字修饰成员变量表示静态的含义,此时成员变量由对象层级提升为类层级
也就是整个类只有一份并被所有对象共享,该成员变量随着类的加载准备就绪,与是否创建对象无关
而被静态static修饰的东西(变量,方法)都放在方法区中
static关键字修饰的成员变量可以使用引用.的方式访问(但最终也是去方法区里而已,即也操作类名.的方式的,这也是为什么this不能操作静态的原因,因为this就不会去方法区里面获取),但推荐类名.的方式
但是一般类名.的方式只有在public下才可以,否则是不行的,这个时候基本只能操作引用了,因为类名.的方式代表是项目全局的,这是一个规定
static关键字的使用方式------------------------------
在非静态成员方法中既能访问非静态的成员又能访问静态的成员
(成员:成员变量 + 成员方法,静态成员被所有对象共享)
在静态成员方法中只能访问静态成员变量不能访问非静态成员
(成员:成员变量 + 成员方法,因为此时可能还没有创建对象)
在以后的开发中只有隶属于类层级并被所有对象共享的内容才可以使用
static关键字修饰(不能滥用static关键字)
public class StaticTest {
private int cnt = 1 ;
private static int snt = 2 ;
public void show ( ) {
System . out. println ( "cnt = " + this . cnt) ;
System . out. println ( "snt = " + this . snt) ;
}
public static void test ( ) {
System . out. println ( "snt = " + snt) ;
}
public static void main ( String [ ] args) {
StaticTest st = new StaticTest ( ) ;
st. show ( ) ;
System . out. println ( "-----------------------------------------------" ) ;
StaticTest . test ( ) ;
}
}
构造块和静态代码块------------------------------
构造块:在类体中直接使用{}括起来的代码块
每创建一个对象都会执行一次构造块
静态代码块:使用static关键字修饰的构造块
静态代码块随着类加载时执行一次
public class BlockTest {
{
System . out. println ( "构造块" ) ;
}
static {
System . out. println ( "静态代码块" ) ;
}
public BlockTest ( ) {
System . out. println ( "构造方法体!" ) ;
}
public static void main ( String [ ] args) {
BlockTest bt = new BlockTest ( ) ;
BlockTest bt2 = new BlockTest ( ) ;
}
}
main方法的详解------------------------------
语法格式
public static void main ( String [ ] args) { }
参数使用的举例
public class MainTest {
public static void main ( String [ ] args) {
System . out. println ( "参数数组中元素的个数是:" + args. length) ;
System . out. println ( "传递给main方法的实际参数为:" ) ;
for ( int i = 0 ; i< args. length; i++ ) {
System . out. println ( "下标为" + i + "的形参变量数值为:" + args[ i] ) ;
}
}
}
案例题目------------------------------
编程实现Singleton类的封装
编程实现singletonTest类对Singleton类进行测试,要求main方法中能得到且只能得到该类的一个对象
public class Singleton {
private static Singleton sin = null ;
private Singleton ( ) { }
public static Singleton getInstance ( ) {
if ( null == sin) {
sin = new Singleton ( ) ;
}
return sin;
}
}
public class SingletonTest {
public static void main ( String [ ] args) {
Singleton s1 = Singleton . getInstance ( ) ;
Singleton s2 = Singleton . getInstance ( ) ;
System . out. println ( s1 == s2) ;
}
}
对于封装------------------------------
当对非静态,静态,对象的东西都进行封装操作时,都是防止其他类乱用封装的类的一些东西而设置的
静态变量隶属于类层级并被所有对象共享,所以静态变量的内存空间依然在方法区
在某些特殊场合中,一个类对外提供且只提供一个对象时,这样的类叫做单例类,而设计单例的流程和思想叫做单例模式
私有化构造方法,使用private关键字修饰
声明本类类型的引用指向本类类型的对象,并使用private static关键字共同修饰
提供公有的get方法负责将对象返回出去,并使用public static关键字共同修饰
单例设计模式的实现方式有两种:饿汉式和懒汉式,在以后的开发中推荐饿汉式(虽然没有使用时,会多一个对象,但是考虑锁或者多线程来说,一般需要大量的多线程,那么是好的,而公司用户多,线程自然多,所以公司一般使用饿汉式,虽然也可以使用懒汉式,具体看自己如何操作了)
之所以不用懒汉式则是考虑多线程资源占用
继承的由来和概念------------------------------
当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类
让多个类吸收公共类中已有的特征和行为而在多个类型只需要编写自己独有特征和行为的机制,叫做继承
在Java语言中使用extends(扩展)关键字来表示继承关系
如:
public class Worker extends Person2{} -表示Worker类继承自Person2类
其中Person2类叫做超类,父类,基类
其中Worker类叫做派生类,子类,孩子类
public class Person2 {
private String name;
private int age;
public Person2 ( ) {
System . out. println ( "Person2()" ) ;
}
public Person2 ( String name, int age) {
System . out. println ( "Person2(String, int)" ) ;
setName ( name) ;
setAge ( age) ;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age) {
if ( age > 0 && age < 150 ) {
this . age = age;
} else {
System . out. println ( "年龄不合理哦!!!" ) ;
}
}
public void show ( ) {
System . out. println ( "我是" + getName ( ) + ",今年" + getAge ( ) + "岁了!" ) ;
}
public void eat ( String food) {
System . out. println ( food + "真好吃!" ) ;
}
public void play ( String game) {
System . out. println ( game + "真好玩!" ) ;
}
}
public class Worker extends Person2 {
private int salary;
public Worker ( ) {
super ( ) ;
System . out. println ( "Worker()" ) ;
}
public Worker ( String name, int age, int salary) {
super ( name, age) ;
System . out. println ( "Worker(String, int, int)" ) ;
setSalary ( salary) ;
}
public int getSalary ( ) {
return salary;
}
public void setSalary ( int salary) {
if ( salary >= 2200 ) {
this . salary = salary;
} else {
System . out. println ( "薪水不合理哦!!!" ) ;
}
}
public void work ( ) {
System . out. println ( "今天的砖头有点烫手..." ) ;
}
@Override
public void show ( ) {
super . show ( ) ;
System . out. println ( "我的薪水是:" + getSalary ( ) ) ;
}
}
使用继承提高了代码的复用性,可维护性及扩展性,是多态的前提条件(因为主要需要类来进行操作,而不是接口(不能操作),内部类也是类哦)
子类不能继承父类的构造方法,私有方法和私有成员变量可以被继承只是不能直接访问,其他的基本上都可以被继承(包括静态)
这个继承的意思可以说是子类算作大格子,父类算小格子
且该小格子在大格子里,即大格子可以调用小格子的东西,但私有的不可以直接调用
即可以说子类继承父类的私有的东西,也可以说子类不继承父类的私有的东西
无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法
来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加代码super()的效果
public class WorkerTest {
public static void main ( String [ ] args) {
Worker w1 = new Worker ( ) ;
w1. show ( ) ;
System . out. println ( "----------------------------------" ) ;
Worker w2 = new Worker ( "zhangfei" , 30 , 3000 ) ;
w2. show ( ) ;
w2. eat ( "豆芽" ) ;
w2. play ( "王者荣耀" ) ;
w2. work ( ) ;
System . out. println ( w2. getName ( ) ) ;
}
}
public class Teacher extends Person {
}
public class TeacherTest {
public static void main ( String [ ] args) {
Teacher t1 = new Teacher ( ) ;
t1. show ( ) ;
}
}
public class ComputerTeacher extends Teacher {
}
使用继承必须满足逻辑关系:子类 is a 父类(is a:一种),也就是不能滥用继承
Java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父类,但一个父类可以有多个子类
C++可以多继承,可能各有优点,具体可以百度
从父类中继承下来的方法不满足子类的需求时,就需要在子类中重新写一个和父类一样的方法来覆盖从父类中继承下来的版本
该方式就叫做方法的重写(Override),注意:无论是继承类,还是实现接口(后面会说明的)基本都是如此
方法重写的原则------------------------------
要求方法名相同,参数列表相同以及返回值类型相同,从Java5开始允许返回子类类型
即当返回值类型为父类时,重写的返回值类型可以改变为子类类型(考虑多态了)
要求方法的访问权限不能变小,可以相同或者变大,extends(继承)可以叫做扩展,即扩展类的东西
要求方法不能抛出更大的异常(异常机制)
注意:super一般不会改变this,this还是子的